Home | History | Annotate | Download | only in ch
      1 /*
      2  * Copyright (c) 2001, 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 /**
     36  * An implementation of Selector for Solaris.
     37  */
     38 
     39 class PollSelectorImpl
     40     extends AbstractPollSelectorImpl
     41 {
     42 
     43     // File descriptors used for interrupt
     44     private int fd0;
     45     private int fd1;
     46 
     47     // Lock for interrupt triggering and clearing
     48     private Object interruptLock = new Object();
     49     private boolean interruptTriggered = false;
     50 
     51     /**
     52      * Package private constructor called by factory method in
     53      * the abstract superclass Selector.
     54      */
     55     PollSelectorImpl(SelectorProvider sp) {
     56         super(sp, 1, 1);
     57         long pipeFds = IOUtil.makePipe(false);
     58         fd0 = (int) (pipeFds >>> 32);
     59         fd1 = (int) pipeFds;
     60         pollWrapper = new PollArrayWrapper(INIT_CAP);
     61         pollWrapper.initInterrupt(fd0, fd1);
     62         channelArray = new SelectionKeyImpl[INIT_CAP];
     63     }
     64 
     65     protected int doSelect(long timeout)
     66         throws IOException
     67     {
     68         if (channelArray == null)
     69             throw new ClosedSelectorException();
     70         processDeregisterQueue();
     71         try {
     72             begin();
     73             pollWrapper.poll(totalChannels, 0, timeout);
     74         } finally {
     75             end();
     76         }
     77         processDeregisterQueue();
     78         int numKeysUpdated = updateSelectedKeys();
     79         if (pollWrapper.getReventOps(0) != 0) {
     80             // Clear the wakeup pipe
     81             pollWrapper.putReventOps(0, 0);
     82             synchronized (interruptLock) {
     83                 IOUtil.drain(fd0);
     84                 interruptTriggered = false;
     85             }
     86         }
     87         return numKeysUpdated;
     88     }
     89 
     90     protected void implCloseInterrupt() throws IOException {
     91         // prevent further wakeup
     92         synchronized (interruptLock) {
     93             interruptTriggered = true;
     94         }
     95         FileDispatcherImpl.closeIntFD(fd0);
     96         FileDispatcherImpl.closeIntFD(fd1);
     97         fd0 = -1;
     98         fd1 = -1;
     99         pollWrapper.release(0);
    100     }
    101 
    102     public Selector wakeup() {
    103         synchronized (interruptLock) {
    104             if (!interruptTriggered) {
    105                 pollWrapper.interrupt();
    106                 interruptTriggered = true;
    107             }
    108         }
    109         return this;
    110     }
    111 
    112 }
    113