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      */
PollSelectorImpl(SelectorProvider sp)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 
doSelect(long timeout)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 
implCloseInterrupt()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 
wakeup()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