Save This Page
Home » openjdk-7 » sun » nio » ch » [javadoc | source]
    1   /*
    2    * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package sun.nio.ch;
   27   
   28   import java.io.IOException;
   29   import java.nio.channels;
   30   import java.nio.channels.spi;
   31   import java.util;
   32   import sun.misc;
   33   
   34   /**
   35    * An implementation of Selector for Linux 2.6+ kernels that uses
   36    * the epoll event notification facility.
   37    */
   38   class EPollSelectorImpl
   39       extends SelectorImpl
   40   {
   41   
   42       // File descriptors used for interrupt
   43       protected int fd0;
   44       protected int fd1;
   45   
   46       // The poll object
   47       EPollArrayWrapper pollWrapper;
   48   
   49       // Maps from file descriptors to keys
   50       private Map<Integer,SelectionKeyImpl> fdToKey;
   51   
   52       // True if this Selector has been closed
   53       private volatile boolean closed = false;
   54   
   55       // Lock for interrupt triggering and clearing
   56       private Object interruptLock = new Object();
   57       private boolean interruptTriggered = false;
   58   
   59       /**
   60        * Package private constructor called by factory method in
   61        * the abstract superclass Selector.
   62        */
   63       EPollSelectorImpl(SelectorProvider sp) {
   64           super(sp);
   65           long pipeFds = IOUtil.makePipe(false);
   66           fd0 = (int) (pipeFds >>> 32);
   67           fd1 = (int) pipeFds;
   68           pollWrapper = new EPollArrayWrapper();
   69           pollWrapper.initInterrupt(fd0, fd1);
   70           fdToKey = new HashMap<Integer,SelectionKeyImpl>();
   71       }
   72   
   73       protected int doSelect(long timeout)
   74           throws IOException
   75       {
   76           if (closed)
   77               throw new ClosedSelectorException();
   78           processDeregisterQueue();
   79           try {
   80               begin();
   81               pollWrapper.poll(timeout);
   82           } finally {
   83               end();
   84           }
   85           processDeregisterQueue();
   86           int numKeysUpdated = updateSelectedKeys();
   87           if (pollWrapper.interrupted()) {
   88               // Clear the wakeup pipe
   89               pollWrapper.putEventOps(pollWrapper.interruptedIndex(), 0);
   90               synchronized (interruptLock) {
   91                   pollWrapper.clearInterrupted();
   92                   IOUtil.drain(fd0);
   93                   interruptTriggered = false;
   94               }
   95           }
   96           return numKeysUpdated;
   97       }
   98   
   99       /**
  100        * Update the keys whose fd's have been selected by the epoll.
  101        * Add the ready keys to the ready queue.
  102        */
  103       private int updateSelectedKeys() {
  104           int entries = pollWrapper.updated;
  105           int numKeysUpdated = 0;
  106           for (int i=0; i<entries; i++) {
  107               int nextFD = pollWrapper.getDescriptor(i);
  108               SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
  109               // ski is null in the case of an interrupt
  110               if (ski != null) {
  111                   int rOps = pollWrapper.getEventOps(i);
  112                   if (selectedKeys.contains(ski)) {
  113                       if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
  114                           numKeysUpdated++;
  115                       }
  116                   } else {
  117                       ski.channel.translateAndSetReadyOps(rOps, ski);
  118                       if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
  119                           selectedKeys.add(ski);
  120                           numKeysUpdated++;
  121                       }
  122                   }
  123               }
  124           }
  125           return numKeysUpdated;
  126       }
  127   
  128       protected void implClose() throws IOException {
  129           if (closed)
  130               return;
  131           closed = true;
  132   
  133           // prevent further wakeup
  134           synchronized (interruptLock) {
  135               interruptTriggered = true;
  136           }
  137   
  138           FileDispatcherImpl.closeIntFD(fd0);
  139           FileDispatcherImpl.closeIntFD(fd1);
  140   
  141           pollWrapper.closeEPollFD();
  142           // it is possible
  143           selectedKeys = null;
  144   
  145           // Deregister channels
  146           Iterator<SelectionKey> i = keys.iterator();
  147           while (i.hasNext()) {
  148               SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
  149               deregister(ski);
  150               SelectableChannel selch = ski.channel();
  151               if (!selch.isOpen() && !selch.isRegistered())
  152                   ((SelChImpl)selch).kill();
  153               i.remove();
  154           }
  155   
  156           fd0 = -1;
  157           fd1 = -1;
  158       }
  159   
  160       protected void implRegister(SelectionKeyImpl ski) {
  161           if (closed)
  162               throw new ClosedSelectorException();
  163           SelChImpl ch = ski.channel;
  164           fdToKey.put(Integer.valueOf(ch.getFDVal()), ski);
  165           pollWrapper.add(ch);
  166           keys.add(ski);
  167       }
  168   
  169       protected void implDereg(SelectionKeyImpl ski) throws IOException {
  170           assert (ski.getIndex() >= 0);
  171           SelChImpl ch = ski.channel;
  172           int fd = ch.getFDVal();
  173           fdToKey.remove(Integer.valueOf(fd));
  174           pollWrapper.release(ch);
  175           ski.setIndex(-1);
  176           keys.remove(ski);
  177           selectedKeys.remove(ski);
  178           deregister((AbstractSelectionKey)ski);
  179           SelectableChannel selch = ski.channel();
  180           if (!selch.isOpen() && !selch.isRegistered())
  181               ((SelChImpl)selch).kill();
  182       }
  183   
  184       void putEventOps(SelectionKeyImpl sk, int ops) {
  185           if (closed)
  186               throw new ClosedSelectorException();
  187           pollWrapper.setInterest(sk.channel, ops);
  188       }
  189   
  190       public Selector wakeup() {
  191           synchronized (interruptLock) {
  192               if (!interruptTriggered) {
  193                   pollWrapper.interrupt();
  194                   interruptTriggered = true;
  195               }
  196           }
  197           return this;
  198       }
  199   
  200       static {
  201           Util.load();
  202       }
  203   
  204   }

Save This Page
Home » openjdk-7 » sun » nio » ch » [javadoc | source]