Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/windows/native/libnio/ch/WindowsSelectorImpl.c
41134 views
1
/*
2
* Copyright (c) 2002, 2021, 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 <limits.h>
36
#include <stdlib.h>
37
#include <winsock2.h>
38
39
#include "jvm.h"
40
#include "jni.h"
41
#include "jni_util.h"
42
#include "nio.h"
43
#include "sun_nio_ch_WindowsSelectorImpl.h"
44
#include "sun_nio_ch_PollArrayWrapper.h"
45
46
#include "nio_util.h" /* Needed for POLL* constants (includes "winsock2.h") */
47
48
typedef struct {
49
jint fd;
50
jshort events;
51
} pollfd;
52
53
#define WAKEUP_SOCKET_BUF_SIZE 16
54
55
56
JNIEXPORT jint JNICALL
57
Java_sun_nio_ch_WindowsSelectorImpl_00024SubSelector_poll0(JNIEnv *env, jobject this,
58
jlong pollAddress, jint numfds,
59
jintArray returnReadFds, jintArray returnWriteFds,
60
jintArray returnExceptFds, jlong timeout, jlong fdsBuffer)
61
{
62
DWORD result = 0;
63
pollfd *fds = (pollfd *) pollAddress;
64
int i;
65
FD_SET *readfds = (FD_SET *) jlong_to_ptr(fdsBuffer);
66
FD_SET *writefds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET));
67
FD_SET *exceptfds = (FD_SET *) jlong_to_ptr(fdsBuffer + sizeof(FD_SET) * 2);
68
struct timeval timevalue, *tv;
69
static struct timeval zerotime = {0, 0};
70
int read_count = 0, write_count = 0, except_count = 0;
71
72
#ifdef _WIN64
73
int resultbuf[FD_SETSIZE + 1];
74
#endif
75
76
if (timeout == 0) {
77
tv = &zerotime;
78
} else if (timeout < 0) {
79
tv = NULL;
80
} else {
81
jlong sec = timeout / 1000;
82
tv = &timevalue;
83
//
84
// struct timeval members are signed 32-bit integers so the
85
// signed 64-bit jlong needs to be clamped
86
//
87
if (sec > INT_MAX) {
88
tv->tv_sec = INT_MAX;
89
tv->tv_usec = 0;
90
} else {
91
tv->tv_sec = (long)sec;
92
tv->tv_usec = (long)((timeout % 1000) * 1000);
93
}
94
}
95
96
/* Set FD_SET structures required for select */
97
for (i = 0; i < numfds; i++) {
98
if (fds[i].events & POLLIN) {
99
readfds->fd_array[read_count] = fds[i].fd;
100
read_count++;
101
}
102
if (fds[i].events & POLLOUT) {
103
writefds->fd_array[write_count] = fds[i].fd;
104
write_count++;
105
}
106
exceptfds->fd_array[except_count] = fds[i].fd;
107
except_count++;
108
}
109
110
readfds->fd_count = read_count;
111
writefds->fd_count = write_count;
112
exceptfds->fd_count = except_count;
113
114
/* Call select */
115
if ((result = select(0 , readfds, writefds, exceptfds, tv))
116
== SOCKET_ERROR) {
117
JNU_ThrowIOExceptionWithLastError(env, "Select failed");
118
return IOS_THROWN;
119
}
120
121
/* Return selected sockets. */
122
/* Each Java array consists of sockets count followed by sockets list */
123
124
#ifdef _WIN64
125
resultbuf[0] = readfds->fd_count;
126
for (i = 0; i < (int)readfds->fd_count; i++) {
127
resultbuf[i + 1] = (int)readfds->fd_array[i];
128
}
129
(*env)->SetIntArrayRegion(env, returnReadFds, 0,
130
readfds->fd_count + 1, resultbuf);
131
132
resultbuf[0] = writefds->fd_count;
133
for (i = 0; i < (int)writefds->fd_count; i++) {
134
resultbuf[i + 1] = (int)writefds->fd_array[i];
135
}
136
(*env)->SetIntArrayRegion(env, returnWriteFds, 0,
137
writefds->fd_count + 1, resultbuf);
138
139
resultbuf[0] = exceptfds->fd_count;
140
for (i = 0; i < (int)exceptfds->fd_count; i++) {
141
resultbuf[i + 1] = (int)exceptfds->fd_array[i];
142
}
143
(*env)->SetIntArrayRegion(env, returnExceptFds, 0,
144
exceptfds->fd_count + 1, resultbuf);
145
#else
146
(*env)->SetIntArrayRegion(env, returnReadFds, 0,
147
readfds->fd_count + 1, (jint *)readfds);
148
149
(*env)->SetIntArrayRegion(env, returnWriteFds, 0,
150
writefds->fd_count + 1, (jint *)writefds);
151
(*env)->SetIntArrayRegion(env, returnExceptFds, 0,
152
exceptfds->fd_count + 1, (jint *)exceptfds);
153
#endif
154
return 0;
155
}
156
157
JNIEXPORT void JNICALL
158
Java_sun_nio_ch_WindowsSelectorImpl_setWakeupSocket0(JNIEnv *env, jclass this,
159
jint scoutFd)
160
{
161
/* Write one byte into the pipe */
162
const char byte = 1;
163
send(scoutFd, &byte, 1, 0);
164
}
165
166
JNIEXPORT void JNICALL
167
Java_sun_nio_ch_WindowsSelectorImpl_resetWakeupSocket0(JNIEnv *env, jclass this,
168
jint scinFd)
169
{
170
char bytes[WAKEUP_SOCKET_BUF_SIZE];
171
long bytesToRead;
172
173
/* Drain socket */
174
/* Find out how many bytes available for read */
175
ioctlsocket (scinFd, FIONREAD, &bytesToRead);
176
if (bytesToRead == 0) {
177
return;
178
}
179
/* Prepare corresponding buffer if needed, and then read */
180
if (bytesToRead > WAKEUP_SOCKET_BUF_SIZE) {
181
char* buf = (char*)malloc(bytesToRead);
182
if (buf == NULL) {
183
JNU_ThrowOutOfMemoryError(env, NULL);
184
return;
185
}
186
recv(scinFd, buf, bytesToRead, 0);
187
free(buf);
188
} else {
189
recv(scinFd, bytes, WAKEUP_SOCKET_BUF_SIZE, 0);
190
}
191
}
192
193