• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000, 2008, 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.net.SocketException;
32 import java.util.*;
33 import sun.misc.*;
34 
35 
36 /**
37  * Base Selector implementation class.
38  */
39 
40 abstract class SelectorImpl
41     extends AbstractSelector
42 {
43 
44     // The set of keys with data ready for an operation
45     protected Set<SelectionKey> selectedKeys;
46 
47     // The set of keys registered with this Selector
48     protected HashSet<SelectionKey> keys;
49 
50     // Public views of the key sets
51     private Set<SelectionKey> publicKeys;             // Immutable
52     private Set<SelectionKey> publicSelectedKeys;     // Removal allowed, but not addition
53 
SelectorImpl(SelectorProvider sp)54     protected SelectorImpl(SelectorProvider sp) {
55         super(sp);
56         keys = new HashSet<SelectionKey>();
57         selectedKeys = new HashSet<SelectionKey>();
58         if (Util.atBugLevel("1.4")) {
59             publicKeys = keys;
60             publicSelectedKeys = selectedKeys;
61         } else {
62             publicKeys = Collections.unmodifiableSet(keys);
63             publicSelectedKeys = Util.ungrowableSet(selectedKeys);
64         }
65     }
66 
keys()67     public Set<SelectionKey> keys() {
68         if (!isOpen() && !Util.atBugLevel("1.4"))
69             throw new ClosedSelectorException();
70         return publicKeys;
71     }
72 
selectedKeys()73     public Set<SelectionKey> selectedKeys() {
74         if (!isOpen() && !Util.atBugLevel("1.4"))
75             throw new ClosedSelectorException();
76         return publicSelectedKeys;
77     }
78 
doSelect(long timeout)79     protected abstract int doSelect(long timeout) throws IOException;
80 
lockAndDoSelect(long timeout)81     private int lockAndDoSelect(long timeout) throws IOException {
82         synchronized (this) {
83             if (!isOpen())
84                 throw new ClosedSelectorException();
85             synchronized (publicKeys) {
86                 synchronized (publicSelectedKeys) {
87                     return doSelect(timeout);
88                 }
89             }
90         }
91     }
92 
select(long timeout)93     public int select(long timeout)
94         throws IOException
95     {
96         if (timeout < 0)
97             throw new IllegalArgumentException("Negative timeout");
98         return lockAndDoSelect((timeout == 0) ? -1 : timeout);
99     }
100 
select()101     public int select() throws IOException {
102         return select(0);
103     }
104 
selectNow()105     public int selectNow() throws IOException {
106         return lockAndDoSelect(0);
107     }
108 
implCloseSelector()109     public void implCloseSelector() throws IOException {
110         wakeup();
111         synchronized (this) {
112             synchronized (publicKeys) {
113                 synchronized (publicSelectedKeys) {
114                     implClose();
115                 }
116             }
117         }
118     }
119 
implClose()120     protected abstract void implClose() throws IOException;
121 
putEventOps(SelectionKeyImpl sk, int ops)122     void putEventOps(SelectionKeyImpl sk, int ops) { }
123 
register(AbstractSelectableChannel ch, int ops, Object attachment)124     protected final SelectionKey register(AbstractSelectableChannel ch,
125                                           int ops,
126                                           Object attachment)
127     {
128         if (!(ch instanceof SelChImpl))
129             throw new IllegalSelectorException();
130         SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
131         k.attach(attachment);
132         synchronized (publicKeys) {
133             implRegister(k);
134         }
135         k.interestOps(ops);
136         return k;
137     }
138 
implRegister(SelectionKeyImpl ski)139     protected abstract void implRegister(SelectionKeyImpl ski);
140 
processDeregisterQueue()141     void processDeregisterQueue() throws IOException {
142         // Precondition: Synchronized on this, keys, and selectedKeys
143         Set cks = cancelledKeys();
144         synchronized (cks) {
145             if (!cks.isEmpty()) {
146                 Iterator i = cks.iterator();
147                 while (i.hasNext()) {
148                     SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
149                     try {
150                         implDereg(ski);
151                     } catch (SocketException se) {
152                         IOException ioe = new IOException(
153                             "Error deregistering key");
154                         ioe.initCause(se);
155                         throw ioe;
156                     } finally {
157                         i.remove();
158                     }
159                 }
160             }
161         }
162     }
163 
implDereg(SelectionKeyImpl ski)164     protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
165 
wakeup()166     abstract public Selector wakeup();
167 
168 }
169