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/demo/jni/Poller/Poller.java
32287 views
1
/*
2
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
*
8
* - Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
*
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* - Neither the name of Oracle nor the names of its
16
* contributors may be used to endorse or promote products derived
17
* from this software without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
*/
31
32
/*
33
* This source code is provided to illustrate the usage of a given feature
34
* or technique and has been deliberately simplified. Additional steps
35
* required for a production-quality application, such as security checks,
36
* input validation and proper error handling, might not be present in
37
* this sample code.
38
*/
39
40
41
import java.lang.reflect.*;
42
import java.io.*;
43
import java.net.*;
44
45
/**
46
* This class is provided for access to the underlying poll(2)
47
* or /dev/poll kernel interfaces. This may be needed for
48
* multiplexing IO when an application cannot afford to have
49
* a thread block on each outstanding IO request.
50
*
51
* It currently supports the same basic functionality as the
52
* C poll(2) API, although for efficiency we needed to avoid
53
* passing the entire pollfd array for every call. See man
54
* pages for poll(2) for info on C API and event types.
55
*
56
*
57
* @author Bruce Chapman
58
* @see java.io.FileDescriptor
59
* @see java.net.Socket
60
* @see attached README.txt
61
* @since JDK1.2
62
*/
63
64
public class Poller {
65
/**
66
* Solaris POLL event types.
67
*/
68
public final static short POLLERR = 0x08;
69
public final static short POLLHUP = 0x10;
70
public final static short POLLNVAL = 0x20;
71
public final static short POLLIN = 1;
72
public final static short POLLPRI = 2;
73
public final static short POLLOUT = 4;
74
public final static short POLLRDNORM = 0x40;
75
public final static short POLLWRNORM = POLLOUT ;
76
public final static short POLLRDBAND = 0x80;
77
public final static short POLLWRBAND = 0x100;
78
public final static short POLLNORM = POLLRDNORM;
79
80
/*
81
* This global synchronization object must be used for all
82
* creation or destruction of Poller objects.
83
*/
84
private final static Object globalSync = new Object();
85
86
/*
87
* The handle for a Poller Object...is used in the JNI C code
88
* where all the associated data is kept.
89
*/
90
private int handle;
91
92
/**
93
* Constructs an instance of a <code>Poller</code> object.
94
* Native code uses sysconf(_SC_OPEN_MAX) to determine how
95
* many fd/skt objects this Poller object can contain.
96
*/
97
public Poller() throws Exception {
98
synchronized(globalSync) {
99
this.handle = nativeCreatePoller(-1);
100
}
101
}
102
103
/**
104
* Constructs an instance of a <code>Poller</code> object.
105
* @param maxFd the maximum number of FileDescriptors/Sockets
106
* this Poller object can contain.
107
*/
108
public Poller(int maxFd) throws Exception {
109
synchronized(globalSync) {
110
this.handle = nativeCreatePoller(maxFd);
111
}
112
}
113
114
/**
115
* Needed to clean up at the JNI C level when object is GCd.
116
*/
117
protected void finalize() throws Throwable {
118
synchronized(globalSync) {
119
nativeDestroyPoller(handle);
120
super.finalize();
121
}
122
}
123
124
/**
125
* Since we can't guarantee WHEN finalize is called, we may
126
* recycle on our own.
127
* @param maxFd the maximum number of FileDescriptors/Sockets
128
* this Poller object can contain.
129
*/
130
public void reset(int maxFd) throws Exception {
131
synchronized(globalSync) {
132
nativeDestroyPoller(handle);
133
this.handle = nativeCreatePoller(maxFd);
134
}
135
}
136
/**
137
* Since we can't guarantee WHEN finalize is called, we may
138
* recycle on our own.
139
*/
140
public void reset() throws Exception {
141
synchronized(globalSync) {
142
nativeDestroyPoller(handle);
143
this.handle = nativeCreatePoller(-1);
144
}
145
}
146
147
/**
148
* Add FileDescriptor to the set handled by this Poller object.
149
*
150
* @param fdObj the FileDescriptor, Socket, or ServerSocket to add.
151
* @param event the bitmask of events we are interested in.
152
* @return the OS level fd associated with this IO Object
153
* (which is what waitMultiple() stores in fds[])
154
*/
155
public synchronized int add(Object fdObj, short event) throws Exception {
156
return nativeAddFd(handle,findfd(fdObj), event);
157
}
158
159
/**
160
* Remove FileDescriptor from the set handled by this Poller object.
161
*
162
* Must be called before the fd/skt is closed.
163
* @param fdObj the FileDescriptor, Socket, or ServerSocket to remove.
164
* @return true if removal succeeded.
165
*/
166
public synchronized boolean remove(Object fdObj) throws Exception {
167
return (nativeRemoveFd(handle,findfd(fdObj)) == 1);
168
}
169
/**
170
* Check if fd or socket is already in the set handled by this Poller object
171
*
172
* @param fdObj the FileDescriptor or [Server]Socket to check.
173
* @return true if fd/skt is in the set for this Poller object.
174
*/
175
public synchronized boolean isMember(Object fdObj) throws Exception {
176
return (nativeIsMember(handle,findfd(fdObj)) == 1);
177
}
178
/**
179
* Wait on Multiple IO Objects.
180
*
181
* @param maxRet the maximum number of fds[] and revents[] to return.
182
* @param fds[] (return) an array of ints in which to store fds with
183
* available data upon a successful non-timeout return.
184
* fds.length must be >= maxRet
185
* @param revents[] (return) the actual events available on the
186
* same-indexed fds[] (i.e. fds[0] has events revents[0])
187
* revents.length must be >= maxRet
188
*
189
* Note : both above arrays are "dense," i.e. only fds[] with events
190
* available are returned.
191
*
192
* @param timeout the maximum number of milliseconds to wait for
193
* events before timing out.
194
* @return the number of fds with triggered events.
195
*
196
* Note : convenience methods exist for skipping the timeout parameter
197
* or the maxRet parameter (in the case of no maxRet, fds.length
198
* must equal revents.length)
199
*
200
* obj.waitMultiple(null,null,timeout) can be used for pausing the LWP
201
* (much more reliable and scalable than Thread.sleep() or Object.wait())
202
*/
203
public synchronized int waitMultiple(int maxRet, int[] fds,short[] revents,
204
long timeout) throws Exception
205
{
206
if ((revents == null) || (fds == null)) {
207
if (maxRet > 0) {
208
throw new NullPointerException("fds or revents is null");
209
}
210
} else if ( (maxRet < 0) ||
211
(maxRet > revents.length) || (maxRet > fds.length) ) {
212
throw new IllegalArgumentException("maxRet out of range");
213
}
214
215
int ret = nativeWait(handle, maxRet, fds, revents, timeout);
216
if (ret < 0) {
217
throw new InterruptedIOException();
218
}
219
return ret;
220
}
221
222
/**
223
* Wait on Multiple IO Objects (no timeout).
224
* A convenience method for waiting indefinitely on IO events
225
*
226
* @see Poller#waitMultiple
227
*
228
*/
229
public int waitMultiple(int maxRet, int[] fds, short[] revents)
230
throws Exception
231
{
232
return waitMultiple(maxRet, fds, revents,-1L); // already synchronized
233
}
234
235
/**
236
* Wait on Multiple IO Objects (no maxRet).
237
* A convenience method for waiting on IO events when the fds
238
* and revents arrays are the same length and that specifies the
239
* maximum number of return events.
240
*
241
* @see Poller#waitMultiple
242
*
243
*/
244
public synchronized int waitMultiple(int[] fds, short[] revents,
245
long timeout) throws Exception
246
{
247
if ((revents == null) && (fds == null)) {
248
return nativeWait(handle,0,null,null,timeout);
249
} else if ((revents == null) || (fds == null)) {
250
throw new NullPointerException("revents or fds is null");
251
} else if (fds.length == revents.length) {
252
return nativeWait(handle, fds.length, fds, revents, timeout);
253
}
254
throw new IllegalArgumentException("fds.length != revents.length");
255
}
256
257
258
/**
259
* Wait on Multiple IO Objects (no maxRet/timeout).
260
* A convenience method for waiting on IO events when the fds
261
* and revents arrays are the same length and that specifies the
262
* maximum number of return events, and when waiting indefinitely
263
* for IO events to occur.
264
*
265
* @see Poller#waitMultiple
266
*
267
*/
268
public int waitMultiple(int[] fds, short[] revents)
269
throws Exception
270
{
271
if ((revents == null) || (fds == null)) {
272
throw new NullPointerException("fds or revents is null");
273
} else if (fds.length == revents.length) {
274
return waitMultiple(revents.length,fds,revents,-1L); // already sync
275
}
276
throw new IllegalArgumentException("fds.length != revents.length");
277
}
278
279
// Utility - get (int) fd from FileDescriptor or [Server]Socket objects.
280
281
private int findfd(Object fdObj) throws Exception {
282
Class cl;
283
Field f;
284
Object val, implVal;
285
286
if ((fdObj instanceof java.net.Socket) ||
287
(fdObj instanceof java.net.ServerSocket)) {
288
cl = fdObj.getClass();
289
f = cl.getDeclaredField("impl");
290
f.setAccessible(true);
291
val = f.get(fdObj);
292
cl = f.getType();
293
f = cl.getDeclaredField("fd");
294
f.setAccessible(true);
295
implVal = f.get(val);
296
cl = f.getType();
297
f = cl.getDeclaredField("fd");
298
f.setAccessible(true);
299
return ((Integer) f.get(implVal)).intValue();
300
} else if ( fdObj instanceof java.io.FileDescriptor ) {
301
cl = fdObj.getClass();
302
f = cl.getDeclaredField("fd");
303
f.setAccessible(true);
304
return ((Integer) f.get(fdObj)).intValue();
305
}
306
else {
307
throw new IllegalArgumentException("Illegal Object type.");
308
}
309
}
310
311
// Actual NATIVE calls
312
313
private static native int nativeInit();
314
private native int nativeCreatePoller(int maxFd) throws Exception;
315
private native void nativeDestroyPoller(int handle) throws Exception;
316
private native int nativeAddFd(int handle, int fd, short events)
317
throws Exception;
318
private native int nativeRemoveFd(int handle, int fd) throws Exception;
319
private native int nativeRemoveIndex(int handle, int index)
320
throws Exception;
321
private native int nativeIsMember(int handle, int fd) throws Exception;
322
private native int nativeWait(int handle, int maxRet, int[] fds,
323
short[] events, long timeout)
324
throws Exception;
325
/**
326
* Get number of active CPUs in this machine
327
* to determine proper level of concurrency.
328
*/
329
public static native int getNumCPUs();
330
331
static {
332
System.loadLibrary("poller");
333
nativeInit();
334
}
335
}
336
337