Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
38829 views
1
/*
2
* Copyright (c) 2011, 2013, 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
/*
27
* KQueueArrayWrapper.java
28
* Implementation of Selector using FreeBSD / Mac OS X kqueues
29
* Derived from Sun's DevPollArrayWrapper
30
*/
31
32
package sun.nio.ch;
33
34
import sun.misc.*;
35
import java.io.IOException;
36
import java.io.FileDescriptor;
37
import java.util.Iterator;
38
import java.util.LinkedList;
39
40
/*
41
* struct kevent { // 32-bit 64-bit
42
* uintptr_t ident; // 4 8
43
* short filter; // 2 2
44
* u_short flags; // 2 2
45
* u_int fflags; // 4 4
46
* intptr_t data; // 4 8
47
* void *udata; // 4 8
48
* } // Total: 20 32
49
*
50
* The implementation works in 32-bit and 64-bit world. We do this by calling a
51
* native function that actually sets the sizes and offsets of the fields based
52
* on which mode we're in.
53
*/
54
55
class KQueueArrayWrapper {
56
// kevent filters
57
static short EVFILT_READ;
58
static short EVFILT_WRITE;
59
60
// kevent struct
61
// These fields are now set by initStructSizes in the static initializer.
62
static short SIZEOF_KEVENT;
63
static short FD_OFFSET;
64
static short FILTER_OFFSET;
65
66
// kevent array size
67
static final int NUM_KEVENTS = 128;
68
69
// Are we in a 64-bit VM?
70
static boolean is64bit = false;
71
72
// The kevent array (used for outcoming events only)
73
private AllocatedNativeObject keventArray = null;
74
private long keventArrayAddress;
75
76
// The kqueue fd
77
private int kq = -1;
78
79
// The fd of the interrupt line going out
80
private int outgoingInterruptFD;
81
82
// The fd of the interrupt line coming in
83
private int incomingInterruptFD;
84
85
static {
86
IOUtil.load();
87
initStructSizes();
88
String datamodel = java.security.AccessController.doPrivileged(
89
new sun.security.action.GetPropertyAction("sun.arch.data.model")
90
);
91
is64bit = datamodel.equals("64");
92
}
93
94
KQueueArrayWrapper() {
95
int allocationSize = SIZEOF_KEVENT * NUM_KEVENTS;
96
keventArray = new AllocatedNativeObject(allocationSize, true);
97
keventArrayAddress = keventArray.address();
98
kq = init();
99
}
100
101
// Used to update file description registrations
102
private static class Update {
103
SelChImpl channel;
104
int events;
105
Update(SelChImpl channel, int events) {
106
this.channel = channel;
107
this.events = events;
108
}
109
}
110
111
private LinkedList<Update> updateList = new LinkedList<Update>();
112
113
void initInterrupt(int fd0, int fd1) {
114
outgoingInterruptFD = fd1;
115
incomingInterruptFD = fd0;
116
register0(kq, fd0, 1, 0);
117
}
118
119
int getReventOps(int index) {
120
int result = 0;
121
int offset = SIZEOF_KEVENT*index + FILTER_OFFSET;
122
short filter = keventArray.getShort(offset);
123
124
// This is all that's necessary based on inspection of usage:
125
// SinkChannelImpl, SourceChannelImpl, DatagramChannelImpl,
126
// ServerSocketChannelImpl, SocketChannelImpl
127
if (filter == EVFILT_READ) {
128
result |= Net.POLLIN;
129
} else if (filter == EVFILT_WRITE) {
130
result |= Net.POLLOUT;
131
}
132
133
return result;
134
}
135
136
int getDescriptor(int index) {
137
int offset = SIZEOF_KEVENT*index + FD_OFFSET;
138
/* The ident field is 8 bytes in 64-bit world, however the API wants us
139
* to return an int. Hence read the 8 bytes but return as an int.
140
*/
141
if (is64bit) {
142
long fd = keventArray.getLong(offset);
143
assert fd <= Integer.MAX_VALUE;
144
return (int) fd;
145
} else {
146
return keventArray.getInt(offset);
147
}
148
}
149
150
void setInterest(SelChImpl channel, int events) {
151
synchronized (updateList) {
152
// update existing registration
153
updateList.add(new Update(channel, events));
154
}
155
}
156
157
void release(SelChImpl channel) {
158
synchronized (updateList) {
159
// flush any pending updates
160
for (Iterator<Update> it = updateList.iterator(); it.hasNext();) {
161
if (it.next().channel == channel) {
162
it.remove();
163
}
164
}
165
166
// remove
167
register0(kq, channel.getFDVal(), 0, 0);
168
}
169
}
170
171
void updateRegistrations() {
172
synchronized (updateList) {
173
Update u = null;
174
while ((u = updateList.poll()) != null) {
175
SelChImpl ch = u.channel;
176
if (!ch.isOpen())
177
continue;
178
179
register0(kq, ch.getFDVal(), u.events & Net.POLLIN, u.events & Net.POLLOUT);
180
}
181
}
182
}
183
184
185
void close() throws IOException {
186
if (keventArray != null) {
187
keventArray.free();
188
keventArray = null;
189
}
190
if (kq >= 0) {
191
FileDispatcherImpl.closeIntFD(kq);
192
kq = -1;
193
}
194
}
195
196
int poll(long timeout) {
197
updateRegistrations();
198
int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout);
199
return updated;
200
}
201
202
void interrupt() {
203
interrupt(outgoingInterruptFD);
204
}
205
206
private native int init();
207
private static native void initStructSizes();
208
209
private native void register0(int kq, int fd, int read, int write);
210
private native int kevent0(int kq, long keventAddress, int keventCount,
211
long timeout);
212
private static native void interrupt(int fd);
213
}
214
215