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