1 /*
2  * Copyright (c) 2001, 2015, 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         try {
61             pollWrapper = new PollArrayWrapper(INIT_CAP);
62             pollWrapper.initInterrupt(fd0, fd1);
63             channelArray = new SelectionKeyImpl[INIT_CAP];
64         } catch (Throwable t) {
65             try {
66                 FileDispatcherImpl.closeIntFD(fd0);
67             } catch (IOException ioe0) {
68                 t.addSuppressed(ioe0);
69             }
70             try {
71                 FileDispatcherImpl.closeIntFD(fd1);
72             } catch (IOException ioe1) {
73                 t.addSuppressed(ioe1);
74             }
75             throw t;
76         }
77     }
78 
doSelect(long timeout)79     protected int doSelect(long timeout)
80         throws IOException
81     {
82         if (channelArray == null)
83             throw new ClosedSelectorException();
84         processDeregisterQueue();
85         try {
86             begin();
87             pollWrapper.poll(totalChannels, 0, timeout);
88         } finally {
89             end();
90         }
91         processDeregisterQueue();
92         int numKeysUpdated = updateSelectedKeys();
93         if (pollWrapper.getReventOps(0) != 0) {
94             // Clear the wakeup pipe
95             pollWrapper.putReventOps(0, 0);
96             synchronized (interruptLock) {
97                 IOUtil.drain(fd0);
98                 interruptTriggered = false;
99             }
100         }
101         return numKeysUpdated;
102     }
103 
implCloseInterrupt()104     protected void implCloseInterrupt() throws IOException {
105         // prevent further wakeup
106         synchronized (interruptLock) {
107             interruptTriggered = true;
108         }
109         FileDispatcherImpl.closeIntFD(fd0);
110         FileDispatcherImpl.closeIntFD(fd1);
111         fd0 = -1;
112         fd1 = -1;
113         pollWrapper.release(0);
114     }
115 
wakeup()116     public Selector wakeup() {
117         synchronized (interruptLock) {
118             if (!interruptTriggered) {
119                 pollWrapper.interrupt();
120                 interruptTriggered = true;
121             }
122         }
123         return this;
124     }
125 
126 }
127