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 */
49
50 /*
51 * @test id=no-vmcontinuations
52 * @requires vm.continuations
53 * @library /test/lib
54 * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:-VMContinuations BlockingSocketOps
55 */
56
57 import java.io.Closeable;
58 import java.io.IOException;
59 import java.io.InputStream;
60 import java.io.OutputStream;
61 import java.net.DatagramPacket;
62 import java.net.DatagramSocket;
63 import java.net.InetAddress;
64 import java.net.InetSocketAddress;
65 import java.net.ServerSocket;
66 import java.net.Socket;
67 import java.net.SocketAddress;
68 import java.net.SocketException;
69 import java.net.SocketTimeoutException;
70
205 } catch (IOException ioe) {
206 // expected
207 }
208 }
209 });
210 }
211
212 /**
213 * Socket close while virtual thread blocked in read.
214 */
215 @Test
216 void testSocketReadAsyncClose1() throws Exception {
217 testSocketReadAsyncClose(0);
218 }
219
220 /**
221 * Socket close while virtual thread blocked in timed read.
222 */
223 @Test
224 void testSocketReadAsyncClose2() throws Exception {
225 testSocketReadAsyncClose(60_000);
226 }
227
228 void testSocketReadAsyncClose(int timeout) throws Exception {
229 VThreadRunner.run(() -> {
230 try (var connection = new Connection()) {
231 Socket s = connection.socket1();
232
233 // delayed close of s
234 runAfterParkedAsync(s::close);
235
236 // read from s should block, then throw
237 if (timeout > 0) {
238 s.setSoTimeout(timeout);
239 }
240 try {
241 int n = s.getInputStream().read();
242 fail("read " + n);
243 } catch (SocketException expected) { }
244 }
245 });
246 }
247
248 /**
249 * Socket shutdownInput while virtual thread blocked in read.
250 */
251 @Test
252 void testSocketReadAsyncShutdownInput1() throws Exception {
253 testSocketReadAsyncShutdownInput(0);
254 }
255
256 /**
257 * Socket shutdownInput while virtual thread blocked in timed read.
258 */
259 @Test
260 void testSocketReadAsyncShutdownInput2() throws Exception {
261 testSocketReadAsyncShutdownInput(60_000);
262 }
263
264 void testSocketReadAsyncShutdownInput(int timeout) throws Exception {
265 VThreadRunner.run(() -> {
266 try (var connection = new Connection()) {
267 Socket s = connection.socket1();
268
269 // delayed shutdown of s
270 runAfterParkedAsync(s::shutdownInput);
271
272 // read from s should block, then throw
273 if (timeout > 0) {
274 s.setSoTimeout(timeout);
275 }
276
277 // -1 or SocketException
278 try {
279 int n = s.getInputStream().read();
280 assertEquals(-1, n);
281 } catch (SocketException e) { }
282 assertFalse(s.isClosed());
283 }
284 });
285 }
286
287 /**
288 * Virtual thread interrupted while blocked in Socket read.
289 */
290 @Test
291 void testSocketReadInterrupt1() throws Exception {
292 testSocketReadInterrupt(0);
293 }
294
295 /**
296 * Virtual thread interrupted while blocked in Socket read with timeout
297 */
298 @Test
299 void testSocketReadInterrupt2() throws Exception {
300 testSocketReadInterrupt(60_000);
301 }
302
303 void testSocketReadInterrupt(int timeout) throws Exception {
304 VThreadRunner.run(() -> {
305 try (var connection = new Connection()) {
306 Socket s = connection.socket1();
317 try {
318 int n = s.getInputStream().read();
319 fail("read " + n);
320 } catch (SocketException expected) {
321 assertTrue(Thread.interrupted());
322 assertTrue(s.isClosed());
323 }
324 }
325 });
326 }
327
328 /**
329 * Socket close while virtual thread blocked in write.
330 */
331 @Test
332 void testSocketWriteAsyncClose() throws Exception {
333 VThreadRunner.run(() -> {
334 try (var connection = new Connection()) {
335 Socket s = connection.socket1();
336
337 // delayed close of s
338 runAfterParkedAsync(s::close);
339
340 // write to s should block, then throw
341 try {
342 byte[] ba = new byte[100*1024];
343 OutputStream out = s.getOutputStream();
344 for (;;) {
345 out.write(ba);
346 }
347 } catch (SocketException expected) { }
348 }
349 });
350 }
351
352 /**
353 * Socket shutdownOutput while virtual thread blocked in write.
354 */
355 @Test
356 void testSocketWriteAsyncShutdownOutput() throws Exception {
357 VThreadRunner.run(() -> {
358 try (var connection = new Connection()) {
359 Socket s = connection.socket1();
360
361 // delayed shutdown of s
362 runAfterParkedAsync(s::shutdownOutput);
363
364 // write to s should block, then throw
365 try {
366 byte[] ba = new byte[100*1024];
367 OutputStream out = s.getOutputStream();
368 for (;;) {
369 out.write(ba);
370 }
371 } catch (SocketException expected) { }
372 assertFalse(s.isClosed());
373 }
374 });
375 }
376
377 /**
378 * Virtual thread interrupted while blocked in Socket write.
379 */
380 @Test
381 void testSocketWriteInterrupt() throws Exception {
382 VThreadRunner.run(() -> {
383 try (var connection = new Connection()) {
384 Socket s = connection.socket1();
385
386 // delayed interrupt of current thread
387 Thread thisThread = Thread.currentThread();
388 runAfterParkedAsync(thisThread::interrupt);
389
390 // write to s should block, then throw
391 try {
392 byte[] ba = new byte[100*1024];
393 OutputStream out = s.getOutputStream();
394 for (;;) {
395 out.write(ba);
396 }
|