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/SocketDispatcher.c
32288 views
1
/*
2
* Copyright (c) 2000, 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
#include <windows.h>
27
#include <winsock2.h>
28
#include <ctype.h>
29
#include "jni.h"
30
#include "jni_util.h"
31
#include "jvm.h"
32
#include "jlong.h"
33
#include "sun_nio_ch_SocketDispatcher.h"
34
#include "nio.h"
35
#include "nio_util.h"
36
37
38
/**************************************************************
39
* SocketDispatcher.c
40
*/
41
42
JNIEXPORT jint JNICALL
43
Java_sun_nio_ch_SocketDispatcher_read0(JNIEnv *env, jclass clazz, jobject fdo,
44
jlong address, jint len)
45
{
46
/* set up */
47
int i = 0;
48
DWORD read = 0;
49
DWORD flags = 0;
50
jint fd = fdval(env, fdo);
51
WSABUF buf;
52
53
/* limit size */
54
if (len > MAX_BUFFER_SIZE)
55
len = MAX_BUFFER_SIZE;
56
57
/* destination buffer and size */
58
buf.buf = (char *)address;
59
buf.len = (u_long)len;
60
61
/* read into the buffers */
62
i = WSARecv((SOCKET)fd, /* Socket */
63
&buf, /* pointers to the buffers */
64
(DWORD)1, /* number of buffers to process */
65
&read, /* receives number of bytes read */
66
&flags, /* no flags */
67
0, /* no overlapped sockets */
68
0); /* no completion routine */
69
70
if (i == SOCKET_ERROR) {
71
int theErr = (jint)WSAGetLastError();
72
if (theErr == WSAEWOULDBLOCK) {
73
return IOS_UNAVAILABLE;
74
}
75
JNU_ThrowIOExceptionWithLastError(env, "Read failed");
76
return IOS_THROWN;
77
}
78
79
return convertReturnVal(env, (jint)read, JNI_TRUE);
80
}
81
82
JNIEXPORT jlong JNICALL
83
Java_sun_nio_ch_SocketDispatcher_readv0(JNIEnv *env, jclass clazz, jobject fdo,
84
jlong address, jint len)
85
{
86
/* set up */
87
int i = 0;
88
DWORD read = 0;
89
DWORD flags = 0;
90
jint fd = fdval(env, fdo);
91
struct iovec *iovp = (struct iovec *)address;
92
WSABUF *bufs = malloc(len * sizeof(WSABUF));
93
jint rem = MAX_BUFFER_SIZE;
94
95
if (bufs == 0) {
96
JNU_ThrowOutOfMemoryError(env, 0);
97
return IOS_THROWN;
98
}
99
100
/* copy iovec into WSABUF */
101
for(i=0; i<len; i++) {
102
jint iov_len = iovp[i].iov_len;
103
if (iov_len > rem)
104
iov_len = rem;
105
bufs[i].buf = (char *)iovp[i].iov_base;
106
bufs[i].len = (u_long)iov_len;
107
rem -= iov_len;
108
if (rem == 0) {
109
len = i+1;
110
break;
111
}
112
}
113
114
/* read into the buffers */
115
i = WSARecv((SOCKET)fd, /* Socket */
116
bufs, /* pointers to the buffers */
117
(DWORD)len, /* number of buffers to process */
118
&read, /* receives number of bytes read */
119
&flags, /* no flags */
120
0, /* no overlapped sockets */
121
0); /* no completion routine */
122
123
/* clean up */
124
free(bufs);
125
126
if (i != 0) {
127
int theErr = (jint)WSAGetLastError();
128
if (theErr == WSAEWOULDBLOCK) {
129
return IOS_UNAVAILABLE;
130
}
131
JNU_ThrowIOExceptionWithLastError(env, "Vector read failed");
132
return IOS_THROWN;
133
}
134
135
return convertLongReturnVal(env, (jlong)read, JNI_TRUE);
136
}
137
138
JNIEXPORT jint JNICALL
139
Java_sun_nio_ch_SocketDispatcher_write0(JNIEnv *env, jclass clazz, jobject fdo,
140
jlong address, jint total)
141
{
142
/* set up */
143
int i = 0;
144
DWORD written = 0;
145
jint count = 0;
146
jint fd = fdval(env, fdo);
147
WSABUF buf;
148
149
do {
150
/* limit size */
151
jint len = total - count;
152
if (len > MAX_BUFFER_SIZE)
153
len = MAX_BUFFER_SIZE;
154
155
/* copy iovec into WSABUF */
156
buf.buf = (char *)address;
157
buf.len = (u_long)len;
158
159
/* write from the buffer */
160
i = WSASend((SOCKET)fd, /* Socket */
161
&buf, /* pointers to the buffers */
162
(DWORD)1, /* number of buffers to process */
163
&written, /* receives number of bytes written */
164
0, /* no flags */
165
0, /* no overlapped sockets */
166
0); /* no completion routine */
167
168
if (i == SOCKET_ERROR) {
169
if (count > 0) {
170
/* can't throw exception when some bytes have been written */
171
break;
172
} else {
173
int theErr = (jint)WSAGetLastError();
174
if (theErr == WSAEWOULDBLOCK) {
175
return IOS_UNAVAILABLE;
176
}
177
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
178
return IOS_THROWN;
179
}
180
}
181
182
count += written;
183
address += written;
184
185
} while ((count < total) && (written == MAX_BUFFER_SIZE));
186
187
return count;
188
}
189
190
JNIEXPORT jlong JNICALL
191
Java_sun_nio_ch_SocketDispatcher_writev0(JNIEnv *env, jclass clazz,
192
jobject fdo, jlong address, jint len)
193
{
194
/* set up */
195
int next_index, next_offset, ret=0;
196
DWORD written = 0;
197
jint fd = fdval(env, fdo);
198
struct iovec *iovp = (struct iovec *)address;
199
WSABUF *bufs = malloc(len * sizeof(WSABUF));
200
jlong count = 0;
201
202
if (bufs == 0) {
203
JNU_ThrowOutOfMemoryError(env, 0);
204
return IOS_THROWN;
205
}
206
207
// next buffer and offset to consume
208
next_index = 0;
209
next_offset = 0;
210
211
while (next_index < len) {
212
DWORD buf_count = 0;
213
214
/* Prepare the WSABUF array to a maximum total size of MAX_BUFFER_SIZE */
215
jint rem = MAX_BUFFER_SIZE;
216
while (next_index < len && rem > 0) {
217
jint iov_len = iovp[next_index].iov_len - next_offset;
218
char* ptr = (char *)iovp[next_index].iov_base;
219
ptr += next_offset;
220
if (iov_len > rem) {
221
iov_len = rem;
222
next_offset += rem;
223
} else {
224
next_index ++;
225
next_offset = 0;
226
}
227
228
bufs[buf_count].buf = ptr;
229
bufs[buf_count].len = (u_long)iov_len;
230
buf_count++;
231
232
rem -= iov_len;
233
}
234
235
/* write the buffers */
236
ret = WSASend((SOCKET)fd, /* Socket */
237
bufs, /* pointers to the buffers */
238
buf_count, /* number of buffers to process */
239
&written, /* receives number of bytes written */
240
0, /* no flags */
241
0, /* no overlapped sockets */
242
0); /* no completion routine */
243
244
if (ret == SOCKET_ERROR) {
245
break;
246
}
247
248
count += written;
249
}
250
251
/* clean up */
252
free(bufs);
253
254
if (ret == SOCKET_ERROR && count == 0) {
255
int theErr = (jint)WSAGetLastError();
256
if (theErr == WSAEWOULDBLOCK) {
257
return IOS_UNAVAILABLE;
258
}
259
JNU_ThrowIOExceptionWithLastError(env, "Vector write failed");
260
return IOS_THROWN;
261
}
262
263
return convertLongReturnVal(env, count, JNI_FALSE);
264
}
265
266
JNIEXPORT void JNICALL
267
Java_sun_nio_ch_SocketDispatcher_preClose0(JNIEnv *env, jclass clazz,
268
jobject fdo)
269
{
270
jint fd = fdval(env, fdo);
271
struct linger l;
272
int len = sizeof(l);
273
if (getsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&l, &len) == 0) {
274
if (l.l_onoff == 0) {
275
WSASendDisconnect(fd, NULL);
276
}
277
}
278
}
279
280
JNIEXPORT void JNICALL
281
Java_sun_nio_ch_SocketDispatcher_close0(JNIEnv *env, jclass clazz,
282
jobject fdo)
283
{
284
jint fd = fdval(env, fdo);
285
if (closesocket(fd) == SOCKET_ERROR) {
286
JNU_ThrowIOExceptionWithLastError(env, "Socket close failed");
287
}
288
}
289
290