1 /*
2 * Copyright (c) 2012, 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
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.Map;
32 import java.util.HashMap;
33 import java.util.Iterator;
34
35 /**
36 * Selector implementation based on the Solaris event port mechanism.
37 */
38
39 class EventPortSelectorImpl
40 extends SelectorImpl
41 {
42 private final EventPortWrapper pollWrapper;
43
44 // Maps from file descriptors to keys
45 private Map<Integer,SelectionKeyImpl> fdToKey;
46
47 // True if this Selector has been closed
48 private boolean closed = false;
49
50 // Lock for interrupt triggering and clearing
51 private final Object interruptLock = new Object();
52 private boolean interruptTriggered = false;
53
54 /**
55 * Package private constructor called by factory method in
56 * the abstract superclass Selector.
57 */
58 EventPortSelectorImpl(SelectorProvider sp) throws IOException {
59 super(sp);
60 pollWrapper = new EventPortWrapper();
61 fdToKey = new HashMap<>();
62 }
63
64 protected int doSelect(long timeout) throws IOException {
65 if (closed)
66 throw new ClosedSelectorException();
67 processDeregisterQueue();
68 int entries;
69 try {
70 begin();
71 entries = pollWrapper.poll(timeout);
72 } finally {
73 end();
74 }
75 processDeregisterQueue();
76 int numKeysUpdated = updateSelectedKeys(entries);
77 if (pollWrapper.interrupted()) {
78 synchronized (interruptLock) {
79 interruptTriggered = false;
80 }
81 }
82 return numKeysUpdated;
83 }
84
85 private int updateSelectedKeys(int entries) {
86 int numKeysUpdated = 0;
88 int nextFD = pollWrapper.getDescriptor(i);
89 SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
90 if (ski != null) {
91 int rOps = pollWrapper.getEventOps(i);
92 if (selectedKeys.contains(ski)) {
93 if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
94 numKeysUpdated++;
95 }
96 } else {
97 ski.channel.translateAndSetReadyOps(rOps, ski);
98 if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
99 selectedKeys.add(ski);
100 numKeysUpdated++;
101 }
102 }
103 }
104 }
105 return numKeysUpdated;
106 }
107
108 protected void implClose() throws IOException {
109 if (closed)
110 return;
111 closed = true;
112
113 // prevent further wakeup
114 synchronized (interruptLock) {
115 interruptTriggered = true;
116 }
117
118 pollWrapper.close();
119 selectedKeys = null;
120
121 // Deregister channels
122 Iterator<SelectionKey> i = keys.iterator();
123 while (i.hasNext()) {
124 SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
125 deregister(ski);
126 SelectableChannel selch = ski.channel();
127 if (!selch.isOpen() && !selch.isRegistered())
128 ((SelChImpl)selch).kill();
129 i.remove();
130 }
131 }
132
133 protected void implRegister(SelectionKeyImpl ski) {
134 int fd = IOUtil.fdVal(ski.channel.getFD());
135 fdToKey.put(Integer.valueOf(fd), ski);
136 keys.add(ski);
137 }
138
139 protected void implDereg(SelectionKeyImpl ski) throws IOException {
140 int i = ski.getIndex();
141 assert (i >= 0);
142 int fd = ski.channel.getFDVal();
143 fdToKey.remove(Integer.valueOf(fd));
144 pollWrapper.release(fd);
145 ski.setIndex(-1);
146 keys.remove(ski);
147 selectedKeys.remove(ski);
148 deregister((AbstractSelectionKey)ski);
149 SelectableChannel selch = ski.channel();
150 if (!selch.isOpen() && !selch.isRegistered())
151 ((SelChImpl)selch).kill();
152 }
153
154 public void putEventOps(SelectionKeyImpl sk, int ops) {
155 if (closed)
156 throw new ClosedSelectorException();
157 int fd = sk.channel.getFDVal();
158 pollWrapper.setInterest(fd, ops);
159 }
160
161 public Selector wakeup() {
162 synchronized (interruptLock) {
163 if (!interruptTriggered) {
164 pollWrapper.interrupt();
165 interruptTriggered = true;
166 }
167 }
168 return this;
169 }
170 }
|
1 /*
2 * Copyright (c) 2012, 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
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.Map;
32 import java.util.HashMap;
33 import java.util.Iterator;
34
35 /**
36 * Selector implementation based on the Solaris event port mechanism.
37 */
38
39 class EventPortSelectorImpl
40 extends SelectorImpl
41 {
42 private final EventPortWrapper pollWrapper;
43
44 // Maps from file descriptors to keys
45 private final Map<Integer, SelectionKeyImpl> fdToKey;
46
47 // True if this Selector has been closed
48 private boolean closed;
49
50 // Lock for interrupt triggering and clearing
51 private final Object interruptLock = new Object();
52 private boolean interruptTriggered;
53
54 /**
55 * Package private constructor called by factory method in
56 * the abstract superclass Selector.
57 */
58 EventPortSelectorImpl(SelectorProvider sp) throws IOException {
59 super(sp);
60 pollWrapper = new EventPortWrapper();
61 fdToKey = new HashMap<>();
62 }
63
64 private void ensureOpen() {
65 if (closed)
66 throw new ClosedSelectorException();
67 }
68
69 @Override
70 protected int doSelect(long timeout) throws IOException {
71 ensureOpen();
72 processDeregisterQueue();
73 int entries;
74 try {
75 begin();
76 entries = pollWrapper.poll(timeout);
77 } finally {
78 end();
79 }
80 processDeregisterQueue();
81 int numKeysUpdated = updateSelectedKeys(entries);
82 if (pollWrapper.interrupted()) {
83 synchronized (interruptLock) {
84 interruptTriggered = false;
85 }
86 }
87 return numKeysUpdated;
88 }
89
90 private int updateSelectedKeys(int entries) {
91 int numKeysUpdated = 0;
93 int nextFD = pollWrapper.getDescriptor(i);
94 SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
95 if (ski != null) {
96 int rOps = pollWrapper.getEventOps(i);
97 if (selectedKeys.contains(ski)) {
98 if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
99 numKeysUpdated++;
100 }
101 } else {
102 ski.channel.translateAndSetReadyOps(rOps, ski);
103 if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
104 selectedKeys.add(ski);
105 numKeysUpdated++;
106 }
107 }
108 }
109 }
110 return numKeysUpdated;
111 }
112
113 @Override
114 protected void implClose() throws IOException {
115 if (closed)
116 return;
117 closed = true;
118
119 // prevent further wakeup
120 synchronized (interruptLock) {
121 interruptTriggered = true;
122 }
123
124 pollWrapper.close();
125
126 // Deregister channels
127 Iterator<SelectionKey> i = keys.iterator();
128 while (i.hasNext()) {
129 SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
130 deregister(ski);
131 SelectableChannel selch = ski.channel();
132 if (!selch.isOpen() && !selch.isRegistered())
133 ((SelChImpl)selch).kill();
134 i.remove();
135 }
136 }
137
138 @Override
139 protected void implRegister(SelectionKeyImpl ski) {
140 int fd = IOUtil.fdVal(ski.channel.getFD());
141 fdToKey.put(Integer.valueOf(fd), ski);
142 keys.add(ski);
143 }
144
145 @Override
146 protected void implDereg(SelectionKeyImpl ski) throws IOException {
147 int i = ski.getIndex();
148 assert (i >= 0);
149 int fd = ski.channel.getFDVal();
150 fdToKey.remove(Integer.valueOf(fd));
151 pollWrapper.release(fd);
152 ski.setIndex(-1);
153 keys.remove(ski);
154 selectedKeys.remove(ski);
155 deregister((AbstractSelectionKey)ski);
156 SelectableChannel selch = ski.channel();
157 if (!selch.isOpen() && !selch.isRegistered())
158 ((SelChImpl)selch).kill();
159 }
160
161 @Override
162 public void putEventOps(SelectionKeyImpl sk, int ops) {
163 ensureOpen();
164 int fd = sk.channel.getFDVal();
165 pollWrapper.setInterest(fd, ops);
166 }
167
168 @Override
169 public Selector wakeup() {
170 synchronized (interruptLock) {
171 if (!interruptTriggered) {
172 pollWrapper.interrupt();
173 interruptTriggered = true;
174 }
175 }
176 return this;
177 }
178 }
|