Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/sun/nio/ch/WindowsSelectorImpl.c
32288 views
1
/*
2
* Copyright (c) 2002, 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
/*
27
*/
28
29
/* Maximum number of sockets per select() */
30
/* This number should be equal to WindowsSelectorImpl.MAX_SELECTABLE_FDS */
31
/* This definition MUST precede the inclusion of winsock2.h */
32
33
#define FD_SETSIZE 1024
34
35
#include <stdlib.h>
36
#include <winsock2.h>
37
38
#include "jvm.h"
39
#include "jni.h"
40
#include "jni_util.h"
41
#include "nio.h"
42
#include "sun_nio_ch_WindowsSelectorImpl.h"
43
#include "sun_nio_ch_PollArrayWrapper.h"
44
45
#include "nio_util.h" /* Needed for POLL* constants (includes "winsock2.h") */
46
47
typedef struct {
48
jint fd;
49
jshort events;
50
} pollfd;
51
52
#define WAKEUP_SOCKET_BUF_SIZE 16
53
54
55
JNIEXPORT jint JNICALL
56
Java_sun_nio_ch_WindowsSelectorImpl_00024SubSelector_poll0(JNIEnv *env, jobject this,
57
jlong pollAddress, jint numfds,
58
jintArray returnReadFds, jintArray returnWriteFds,
59
jintArray returnExceptFds, jlong timeout, jlong fdsBuffer)
60
{
61
DWORD result = 0;
62
pollfd *fds = (pollfd *) pollAddress;
63
int i;
64
FD_SET *readfds = (FD_SET *) jlong_to_ptr(fdsBuffer);
65
FD_SET *writefds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET));
66
FD_SET *exceptfds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET) * 2);
67
struct timeval timevalue, *tv;
68
static struct timeval zerotime = {0, 0};
69
int read_count = 0, write_count = 0, except_count = 0;
70
71
#ifdef _WIN64
72
int resultbuf[FD_SETSIZE + 1];
73
#endif
74
75
if (timeout == 0) {
76
tv = &zerotime;
77
} else if (timeout < 0) {
78
tv = NULL;
79
} else {
80
tv = &timevalue;
81
tv->tv_sec = (long)(timeout / 1000);
82
tv->tv_usec = (long)((timeout % 1000) * 1000);
83
}
84
85
/* Set FD_SET structures required for select */
86
for (i = 0; i < numfds; i++) {
87
if (fds[i].events & POLLIN) {
88
readfds->fd_array[read_count] = fds[i].fd;
89
read_count++;
90
}
91
if (fds[i].events & (POLLOUT | POLLCONN))
92
{
93
writefds->fd_array[write_count] = fds[i].fd;
94
write_count++;
95
}
96
exceptfds->fd_array[except_count] = fds[i].fd;
97
except_count++;
98
}
99
100
readfds->fd_count = read_count;
101
writefds->fd_count = write_count;
102
exceptfds->fd_count = except_count;
103
104
/* Call select */
105
if ((result = select(0 , readfds, writefds, exceptfds, tv))
106
== SOCKET_ERROR) {
107
/* Bad error - this should not happen frequently */
108
/* Iterate over sockets and call select() on each separately */
109
FD_SET *errreadfds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET) * 3);
110
FD_SET *errwritefds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET) * 4);
111
FD_SET *errexceptfds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET) * 5);
112
readfds->fd_count = 0;
113
writefds->fd_count = 0;
114
exceptfds->fd_count = 0;
115
for (i = 0; i < numfds; i++) {
116
/* prepare select structures for the i-th socket */
117
errreadfds->fd_count = 0;
118
errwritefds->fd_count = 0;
119
if (fds[i].events & POLLIN) {
120
errreadfds->fd_array[0] = fds[i].fd;
121
errreadfds->fd_count = 1;
122
}
123
if (fds[i].events & (POLLOUT | POLLCONN))
124
{
125
errwritefds->fd_array[0] = fds[i].fd;
126
errwritefds->fd_count = 1;
127
}
128
errexceptfds->fd_array[0] = fds[i].fd;
129
errexceptfds->fd_count = 1;
130
131
/* call select on the i-th socket */
132
if (select(0, errreadfds, errwritefds, errexceptfds, &zerotime)
133
== SOCKET_ERROR) {
134
/* This socket causes an error. Add it to exceptfds set */
135
exceptfds->fd_array[exceptfds->fd_count] = fds[i].fd;
136
exceptfds->fd_count++;
137
} else {
138
/* This socket does not cause an error. Process result */
139
if (errreadfds->fd_count == 1) {
140
readfds->fd_array[readfds->fd_count] = fds[i].fd;
141
readfds->fd_count++;
142
}
143
if (errwritefds->fd_count == 1) {
144
writefds->fd_array[writefds->fd_count] = fds[i].fd;
145
writefds->fd_count++;
146
}
147
if (errexceptfds->fd_count == 1) {
148
exceptfds->fd_array[exceptfds->fd_count] = fds[i].fd;
149
exceptfds->fd_count++;
150
}
151
}
152
}
153
}
154
155
/* Return selected sockets. */
156
/* Each Java array consists of sockets count followed by sockets list */
157
158
#ifdef _WIN64
159
resultbuf[0] = readfds->fd_count;
160
for (i = 0; i < (int)readfds->fd_count; i++) {
161
resultbuf[i + 1] = (int)readfds->fd_array[i];
162
}
163
(*env)->SetIntArrayRegion(env, returnReadFds, 0,
164
readfds->fd_count + 1, resultbuf);
165
166
resultbuf[0] = writefds->fd_count;
167
for (i = 0; i < (int)writefds->fd_count; i++) {
168
resultbuf[i + 1] = (int)writefds->fd_array[i];
169
}
170
(*env)->SetIntArrayRegion(env, returnWriteFds, 0,
171
writefds->fd_count + 1, resultbuf);
172
173
resultbuf[0] = exceptfds->fd_count;
174
for (i = 0; i < (int)exceptfds->fd_count; i++) {
175
resultbuf[i + 1] = (int)exceptfds->fd_array[i];
176
}
177
(*env)->SetIntArrayRegion(env, returnExceptFds, 0,
178
exceptfds->fd_count + 1, resultbuf);
179
#else
180
(*env)->SetIntArrayRegion(env, returnReadFds, 0,
181
readfds->fd_count + 1, (jint *)readfds);
182
183
(*env)->SetIntArrayRegion(env, returnWriteFds, 0,
184
writefds->fd_count + 1, (jint *)writefds);
185
(*env)->SetIntArrayRegion(env, returnExceptFds, 0,
186
exceptfds->fd_count + 1, (jint *)exceptfds);
187
#endif
188
return 0;
189
}
190
191
JNIEXPORT void JNICALL
192
Java_sun_nio_ch_WindowsSelectorImpl_setWakeupSocket0(JNIEnv *env, jclass this,
193
jint scoutFd)
194
{
195
/* Write one byte into the pipe */
196
const char byte = 1;
197
send(scoutFd, &byte, 1, 0);
198
}
199
200
JNIEXPORT void JNICALL
201
Java_sun_nio_ch_WindowsSelectorImpl_resetWakeupSocket0(JNIEnv *env, jclass this,
202
jint scinFd)
203
{
204
char bytes[WAKEUP_SOCKET_BUF_SIZE];
205
long bytesToRead;
206
207
/* Drain socket */
208
/* Find out how many bytes available for read */
209
ioctlsocket (scinFd, FIONREAD, &bytesToRead);
210
if (bytesToRead == 0) {
211
return;
212
}
213
/* Prepare corresponding buffer if needed, and then read */
214
if (bytesToRead > WAKEUP_SOCKET_BUF_SIZE) {
215
char* buf = (char*)malloc(bytesToRead);
216
if (buf == NULL) {
217
JNU_ThrowOutOfMemoryError(env, NULL);
218
return;
219
}
220
recv(scinFd, buf, bytesToRead, 0);
221
free(buf);
222
} else {
223
recv(scinFd, bytes, WAKEUP_SOCKET_BUF_SIZE, 0);
224
}
225
}
226
227
JNIEXPORT jboolean JNICALL
228
Java_sun_nio_ch_WindowsSelectorImpl_discardUrgentData(JNIEnv* env, jobject this,
229
jint s)
230
{
231
char data[8];
232
jboolean discarded = JNI_FALSE;
233
int n;
234
do {
235
n = recv(s, (char*)&data, sizeof(data), MSG_OOB);
236
if (n > 0) {
237
discarded = JNI_TRUE;
238
}
239
} while (n > 0);
240
return discarded;
241
}
242
243