Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/nio/ch/EPollSelectorImpl.java
32288 views
1
/*
2
* Copyright (c) 2005, 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
* An implementation of Selector for Linux 2.6+ kernels that uses
36
* the epoll event notification facility.
37
*/
38
class EPollSelectorImpl
39
extends SelectorImpl
40
{
41
42
// File descriptors used for interrupt
43
protected int fd0;
44
protected int fd1;
45
46
// The poll object
47
EPollArrayWrapper pollWrapper;
48
49
// Maps from file descriptors to keys
50
private Map<Integer,SelectionKeyImpl> fdToKey;
51
52
// True if this Selector has been closed
53
private volatile boolean closed = false;
54
55
// Lock for interrupt triggering and clearing
56
private final Object interruptLock = new Object();
57
private boolean interruptTriggered = false;
58
59
/**
60
* Package private constructor called by factory method in
61
* the abstract superclass Selector.
62
*/
63
EPollSelectorImpl(SelectorProvider sp) throws IOException {
64
super(sp);
65
long pipeFds = IOUtil.makePipe(false);
66
fd0 = (int) (pipeFds >>> 32);
67
fd1 = (int) pipeFds;
68
try {
69
pollWrapper = new EPollArrayWrapper();
70
pollWrapper.initInterrupt(fd0, fd1);
71
fdToKey = new HashMap<>();
72
} catch (Throwable t) {
73
try {
74
FileDispatcherImpl.closeIntFD(fd0);
75
} catch (IOException ioe0) {
76
t.addSuppressed(ioe0);
77
}
78
try {
79
FileDispatcherImpl.closeIntFD(fd1);
80
} catch (IOException ioe1) {
81
t.addSuppressed(ioe1);
82
}
83
throw t;
84
}
85
}
86
87
protected int doSelect(long timeout) throws IOException {
88
if (closed)
89
throw new ClosedSelectorException();
90
processDeregisterQueue();
91
try {
92
begin();
93
pollWrapper.poll(timeout);
94
} finally {
95
end();
96
}
97
processDeregisterQueue();
98
int numKeysUpdated = updateSelectedKeys();
99
if (pollWrapper.interrupted()) {
100
// Clear the wakeup pipe
101
pollWrapper.putEventOps(pollWrapper.interruptedIndex(), 0);
102
synchronized (interruptLock) {
103
pollWrapper.clearInterrupted();
104
IOUtil.drain(fd0);
105
interruptTriggered = false;
106
}
107
}
108
return numKeysUpdated;
109
}
110
111
/**
112
* Update the keys whose fd's have been selected by the epoll.
113
* Add the ready keys to the ready queue.
114
*/
115
private int updateSelectedKeys() {
116
int entries = pollWrapper.updated;
117
int numKeysUpdated = 0;
118
for (int i=0; i<entries; i++) {
119
int nextFD = pollWrapper.getDescriptor(i);
120
SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
121
// ski is null in the case of an interrupt
122
if (ski != null) {
123
int rOps = pollWrapper.getEventOps(i);
124
if (selectedKeys.contains(ski)) {
125
if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
126
numKeysUpdated++;
127
}
128
} else {
129
ski.channel.translateAndSetReadyOps(rOps, ski);
130
if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
131
selectedKeys.add(ski);
132
numKeysUpdated++;
133
}
134
}
135
}
136
}
137
return numKeysUpdated;
138
}
139
140
protected void implClose() throws IOException {
141
if (closed)
142
return;
143
closed = true;
144
145
// prevent further wakeup
146
synchronized (interruptLock) {
147
interruptTriggered = true;
148
}
149
150
FileDispatcherImpl.closeIntFD(fd0);
151
FileDispatcherImpl.closeIntFD(fd1);
152
153
pollWrapper.closeEPollFD();
154
// it is possible
155
selectedKeys = null;
156
157
// Deregister channels
158
Iterator<SelectionKey> i = keys.iterator();
159
while (i.hasNext()) {
160
SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
161
deregister(ski);
162
SelectableChannel selch = ski.channel();
163
if (!selch.isOpen() && !selch.isRegistered())
164
((SelChImpl)selch).kill();
165
i.remove();
166
}
167
168
fd0 = -1;
169
fd1 = -1;
170
}
171
172
protected void implRegister(SelectionKeyImpl ski) {
173
if (closed)
174
throw new ClosedSelectorException();
175
SelChImpl ch = ski.channel;
176
int fd = Integer.valueOf(ch.getFDVal());
177
fdToKey.put(fd, ski);
178
pollWrapper.add(fd);
179
keys.add(ski);
180
}
181
182
protected void implDereg(SelectionKeyImpl ski) throws IOException {
183
assert (ski.getIndex() >= 0);
184
SelChImpl ch = ski.channel;
185
int fd = ch.getFDVal();
186
fdToKey.remove(Integer.valueOf(fd));
187
pollWrapper.remove(fd);
188
ski.setIndex(-1);
189
keys.remove(ski);
190
selectedKeys.remove(ski);
191
deregister((AbstractSelectionKey)ski);
192
SelectableChannel selch = ski.channel();
193
if (!selch.isOpen() && !selch.isRegistered())
194
((SelChImpl)selch).kill();
195
}
196
197
public void putEventOps(SelectionKeyImpl ski, int ops) {
198
if (closed)
199
throw new ClosedSelectorException();
200
SelChImpl ch = ski.channel;
201
pollWrapper.setInterest(ch.getFDVal(), ops);
202
}
203
204
public Selector wakeup() {
205
synchronized (interruptLock) {
206
if (!interruptTriggered) {
207
pollWrapper.interrupt();
208
interruptTriggered = true;
209
}
210
}
211
return this;
212
}
213
}
214
215