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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test id=default
26 * @bug 8284161
27 * @summary Test virtual threads doing blocking I/O on java.net Sockets
28 * @library /test/lib
29 * @run junit BlockingSocketOps
30 */
31
32 /**
33 * @test id=poller-modes
34 * @requires (os.family == "linux") | (os.family == "mac")
35 * @library /test/lib
36 * @run junit/othervm -Djdk.pollerMode=1 BlockingSocketOps
37 * @run junit/othervm -Djdk.pollerMode=2 BlockingSocketOps
38 */
39
40 /**
41 * @test id=no-vmcontinuations
42 * @requires vm.continuations
43 * @library /test/lib
44 * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
45 */
46
47 import java.io.Closeable;
48 import java.io.IOException;
49 import java.io.InputStream;
50 import java.io.OutputStream;
51 import java.net.DatagramPacket;
52 import java.net.DatagramSocket;
53 import java.net.InetAddress;
54 import java.net.InetSocketAddress;
55 import java.net.ServerSocket;
56 import java.net.Socket;
57 import java.net.SocketAddress;
58 import java.net.SocketException;
59 import java.net.SocketTimeoutException;
60
195 } catch (IOException ioe) {
196 // expected
197 }
198 }
199 });
200 }
201
202 /**
203 * Socket close while virtual thread blocked in read.
204 */
205 @Test
206 void testSocketReadAsyncClose1() throws Exception {
207 testSocketReadAsyncClose(0);
208 }
209
210 /**
211 * Socket close while virtual thread blocked in timed read.
212 */
213 @Test
214 void testSocketReadAsyncClose2() throws Exception {
215 testSocketReadAsyncClose(0);
216 }
217
218 void testSocketReadAsyncClose(int timeout) throws Exception {
219 VThreadRunner.run(() -> {
220 try (var connection = new Connection()) {
221 Socket s = connection.socket1();
222
223 // delayed close of s
224 runAfterParkedAsync(s::close);
225
226 // read from s should block, then throw
227 if (timeout > 0) {
228 s.setSoTimeout(timeout);
229 }
230 try {
231 int n = s.getInputStream().read();
232 fail("read " + n);
233 } catch (SocketException expected) { }
234 }
235 });
236 }
237
238 /**
239 * Virtual thread interrupted while blocked in Socket read.
240 */
241 @Test
242 void testSocketReadInterrupt1() throws Exception {
243 testSocketReadInterrupt(0);
244 }
245
246 /**
247 * Virtual thread interrupted while blocked in Socket read with timeout
248 */
249 @Test
250 void testSocketReadInterrupt2() throws Exception {
251 testSocketReadInterrupt(60_000);
252 }
253
254 void testSocketReadInterrupt(int timeout) throws Exception {
255 VThreadRunner.run(() -> {
256 try (var connection = new Connection()) {
257 Socket s = connection.socket1();
268 try {
269 int n = s.getInputStream().read();
270 fail("read " + n);
271 } catch (SocketException expected) {
272 assertTrue(Thread.interrupted());
273 assertTrue(s.isClosed());
274 }
275 }
276 });
277 }
278
279 /**
280 * Socket close while virtual thread blocked in write.
281 */
282 @Test
283 void testSocketWriteAsyncClose() throws Exception {
284 VThreadRunner.run(() -> {
285 try (var connection = new Connection()) {
286 Socket s = connection.socket1();
287
288 // delayedclose of s
289 runAfterParkedAsync(s::close);
290
291 // write to s should block, then throw
292 try {
293 byte[] ba = new byte[100*1024];
294 OutputStream out = s.getOutputStream();
295 for (;;) {
296 out.write(ba);
297 }
298 } catch (SocketException expected) { }
299 }
300 });
301 }
302
303 /**
304 * Virtual thread interrupted while blocked in Socket write.
305 */
306 @Test
307 void testSocketWriteInterrupt() throws Exception {
308 VThreadRunner.run(() -> {
309 try (var connection = new Connection()) {
310 Socket s = connection.socket1();
311
312 // delayed interrupt of current thread
313 Thread thisThread = Thread.currentThread();
314 runAfterParkedAsync(thisThread::interrupt);
315
316 // write to s should block, then throw
317 try {
318 byte[] ba = new byte[100*1024];
319 OutputStream out = s.getOutputStream();
320 for (;;) {
321 out.write(ba);
322 }
|
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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test id=default
26 * @bug 8284161
27 * @summary Test virtual threads doing blocking I/O on java.net Sockets
28 * @library /test/lib
29 * @run junit BlockingSocketOps
30 */
31
32 /*
33 * @test id=poller-modes
34 * @requires (os.family == "linux") | (os.family == "mac")
35 * @library /test/lib
36 * @run junit/othervm -Djdk.pollerMode=1 BlockingSocketOps
37 * @run junit/othervm -Djdk.pollerMode=2 BlockingSocketOps
38 * @run junit/othervm -Djdk.pollerMode=3 BlockingSocketOps
39 */
40
41 /*
42 * @test id=io_uring
43 * @requires os.family == "linux"
44 * @library /test/lib
45 * @run junit/othervm -Djdk.pollerMode=1 -Djdk.io_uring=true BlockingSocketOps
46 * @run junit/othervm -Djdk.pollerMode=2 -Djdk.io_uring=true BlockingSocketOps
47 * @run junit/othervm -Djdk.pollerMode=3 -Djdk.io_uring=true BlockingSocketOps
48 * @run junit/othervm -Djdk.pollerMode=1 -Djdk.io_uring=true -Djdk.io_uring.sqpoll_idle=20 BlockingSocketOps
49 * @run junit/othervm -Djdk.pollerMode=2 -Djdk.io_uring=true -Djdk.io_uring.sqpoll_idle=20 BlockingSocketOps
50 * @run junit/othervm -Djdk.pollerMode=3 -Djdk.io_uring=true -Djdk.io_uring.sqpoll_idle=20 BlockingSocketOps
51 * @run junit/othervm -Djdk.pollerMode=1 -Djdk.io_uring=true -Djdk.io_uring.read=true -Djdk.io_uring.write=true BlockingSocketOps
52 * @run junit/othervm -Djdk.pollerMode=2 -Djdk.io_uring=true -Djdk.io_uring.read=true -Djdk.io_uring.write=true BlockingSocketOps
53 * @run junit/othervm -Djdk.pollerMode=3 -Djdk.io_uring=true -Djdk.io_uring.read=true -Djdk.io_uring.write=true BlockingSocketOps
54 * @run junit/othervm -Djdk.pollerMode=1 -Djdk.io_uring=true -Djdk.io_uring.read=true -Djdk.io_uring.write=true -Djdk.io_uring.sqpoll_idle=20 BlockingSocketOps
55 * @run junit/othervm -Djdk.pollerMode=2 -Djdk.io_uring=true -Djdk.io_uring.read=true -Djdk.io_uring.write=true -Djdk.io_uring.sqpoll_idle=20 BlockingSocketOps
56 * @run junit/othervm -Djdk.pollerMode=3 -Djdk.io_uring=true -Djdk.io_uring.read=true -Djdk.io_uring.write=true -Djdk.io_uring.sqpoll_idle=20 BlockingSocketOps
57 */
58
59 /*
60 * @test id=no-vmcontinuations
61 * @requires vm.continuations
62 * @library /test/lib
63 * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
64 */
65
66 import java.io.Closeable;
67 import java.io.IOException;
68 import java.io.InputStream;
69 import java.io.OutputStream;
70 import java.net.DatagramPacket;
71 import java.net.DatagramSocket;
72 import java.net.InetAddress;
73 import java.net.InetSocketAddress;
74 import java.net.ServerSocket;
75 import java.net.Socket;
76 import java.net.SocketAddress;
77 import java.net.SocketException;
78 import java.net.SocketTimeoutException;
79
214 } catch (IOException ioe) {
215 // expected
216 }
217 }
218 });
219 }
220
221 /**
222 * Socket close while virtual thread blocked in read.
223 */
224 @Test
225 void testSocketReadAsyncClose1() throws Exception {
226 testSocketReadAsyncClose(0);
227 }
228
229 /**
230 * Socket close while virtual thread blocked in timed read.
231 */
232 @Test
233 void testSocketReadAsyncClose2() throws Exception {
234 testSocketReadAsyncClose(60_000);
235 }
236
237 void testSocketReadAsyncClose(int timeout) throws Exception {
238 VThreadRunner.run(() -> {
239 try (var connection = new Connection()) {
240 Socket s = connection.socket1();
241
242 // delayed close of s
243 runAfterParkedAsync(s::close);
244
245 // read from s should block, then throw
246 if (timeout > 0) {
247 s.setSoTimeout(timeout);
248 }
249 try {
250 int n = s.getInputStream().read();
251 fail("read " + n);
252 } catch (SocketException expected) { }
253 }
254 });
255 }
256
257 /**
258 * Socket shutdownInput while virtual thread blocked in read.
259 */
260 @Test
261 void testSocketReadAsyncShutdownInput1() throws Exception {
262 testSocketReadAsyncShutdownInput(0);
263 }
264
265 /**
266 * Socket shutdownInput while virtual thread blocked in timed read.
267 */
268 @Test
269 void testSocketReadAsyncShutdownInput2() throws Exception {
270 testSocketReadAsyncShutdownInput(60_000);
271 }
272
273 void testSocketReadAsyncShutdownInput(int timeout) throws Exception {
274 VThreadRunner.run(() -> {
275 try (var connection = new Connection()) {
276 Socket s = connection.socket1();
277
278 // delayed shutdown of s
279 runAfterParkedAsync(s::shutdownInput);
280
281 // read from s should block, then throw
282 if (timeout > 0) {
283 s.setSoTimeout(timeout);
284 }
285
286 // -1 or SocketException
287 try {
288 int n = s.getInputStream().read();
289 assertEquals(-1, n);
290 } catch (SocketException e) { }
291 assertFalse(s.isClosed());
292 }
293 });
294 }
295
296 /**
297 * Virtual thread interrupted while blocked in Socket read.
298 */
299 @Test
300 void testSocketReadInterrupt1() throws Exception {
301 testSocketReadInterrupt(0);
302 }
303
304 /**
305 * Virtual thread interrupted while blocked in Socket read with timeout
306 */
307 @Test
308 void testSocketReadInterrupt2() throws Exception {
309 testSocketReadInterrupt(60_000);
310 }
311
312 void testSocketReadInterrupt(int timeout) throws Exception {
313 VThreadRunner.run(() -> {
314 try (var connection = new Connection()) {
315 Socket s = connection.socket1();
326 try {
327 int n = s.getInputStream().read();
328 fail("read " + n);
329 } catch (SocketException expected) {
330 assertTrue(Thread.interrupted());
331 assertTrue(s.isClosed());
332 }
333 }
334 });
335 }
336
337 /**
338 * Socket close while virtual thread blocked in write.
339 */
340 @Test
341 void testSocketWriteAsyncClose() throws Exception {
342 VThreadRunner.run(() -> {
343 try (var connection = new Connection()) {
344 Socket s = connection.socket1();
345
346 // delayed close of s
347 runAfterParkedAsync(s::close);
348
349 // write to s should block, then throw
350 try {
351 byte[] ba = new byte[100*1024];
352 OutputStream out = s.getOutputStream();
353 for (;;) {
354 out.write(ba);
355 }
356 } catch (SocketException expected) { }
357 }
358 });
359 }
360
361 /**
362 * Socket shutdownOutput while virtual thread blocked in write.
363 */
364 @Test
365 void testSocketWriteAsyncShutdownOutput() throws Exception {
366 VThreadRunner.run(() -> {
367 try (var connection = new Connection()) {
368 Socket s = connection.socket1();
369
370 // delayed shutdown of s
371 runAfterParkedAsync(s::shutdownOutput);
372
373 // write to s should block, then throw
374 try {
375 byte[] ba = new byte[100*1024];
376 OutputStream out = s.getOutputStream();
377 for (;;) {
378 out.write(ba);
379 }
380 } catch (SocketException expected) { }
381 assertFalse(s.isClosed());
382 }
383 });
384 }
385
386 /**
387 * Virtual thread interrupted while blocked in Socket write.
388 */
389 @Test
390 void testSocketWriteInterrupt() throws Exception {
391 VThreadRunner.run(() -> {
392 try (var connection = new Connection()) {
393 Socket s = connection.socket1();
394
395 // delayed interrupt of current thread
396 Thread thisThread = Thread.currentThread();
397 runAfterParkedAsync(thisThread::interrupt);
398
399 // write to s should block, then throw
400 try {
401 byte[] ba = new byte[100*1024];
402 OutputStream out = s.getOutputStream();
403 for (;;) {
404 out.write(ba);
405 }
|