1230
1231 /**
1232 * Tasks that sleep for 1 second.
1233 */
1234 static Stream<ThrowingRunnable> oneSecondSleepers() {
1235 return Stream.of(
1236 () -> Thread.sleep(1000),
1237 () -> Thread.sleep(Duration.ofSeconds(1))
1238 );
1239 }
1240
1241 /**
1242 * Test Thread.sleep duration.
1243 */
1244 @ParameterizedTest
1245 @MethodSource("oneSecondSleepers")
1246 void testSleep3(ThrowingRunnable sleeper) throws Exception {
1247 VThreadRunner.run(() -> {
1248 long start = millisTime();
1249 sleeper.run();
1250 expectDuration(start, /*min*/900, /*max*/4000);
1251 });
1252 }
1253
1254 /**
1255 * Tasks that sleep for zero or longer duration.
1256 */
1257 static Stream<ThrowingRunnable> sleepers() {
1258 return Stream.of(
1259 () -> Thread.sleep(0),
1260 () -> Thread.sleep(0, 0),
1261 () -> Thread.sleep(1000),
1262 () -> Thread.sleep(1000, 0),
1263 () -> Thread.sleep(Duration.ofMillis(0)),
1264 () -> Thread.sleep(Duration.ofMillis(1000))
1265 );
1266 }
1267
1268 /**
1269 * Test Thread.sleep with interrupt status set.
1270 */
1320 try {
1321 sleeper.run();
1322 fail("sleep was not interrupted");
1323 } catch (InterruptedException e) {
1324 // interrupt status should be cleared
1325 assertFalse(t.isInterrupted());
1326 }
1327 });
1328 }
1329
1330 /**
1331 * Test that Thread.sleep does not disrupt parking permit.
1332 */
1333 @Test
1334 void testSleep6() throws Exception {
1335 VThreadRunner.run(() -> {
1336 LockSupport.unpark(Thread.currentThread());
1337
1338 long start = millisTime();
1339 Thread.sleep(1000);
1340 expectDuration(start, /*min*/900, /*max*/4000);
1341
1342 // check that parking permit was not consumed
1343 LockSupport.park();
1344 });
1345 }
1346
1347 /**
1348 * Test that Thread.sleep is not disrupted by unparking thread.
1349 */
1350 @Test
1351 void testSleep7() throws Exception {
1352 AtomicReference<Exception> exc = new AtomicReference<>();
1353 var thread = Thread.ofVirtual().start(() -> {
1354 try {
1355 long start = millisTime();
1356 Thread.sleep(1000);
1357 expectDuration(start, /*min*/900, /*max*/4000);
1358 } catch (Exception e) {
1359 exc.set(e);
1360 }
1361
1362 });
1363 // attempt to disrupt sleep
1364 for (int i = 0; i < 5; i++) {
1365 Thread.sleep(20);
1366 LockSupport.unpark(thread);
1367 }
1368 thread.join();
1369 Exception e = exc.get();
1370 if (e != null) {
1371 throw e;
1372 }
1373 }
1374
1375 /**
1376 * Test Thread.sleep when pinned.
1377 */
1378 @Test
1379 void testSleep8() throws Exception {
1380 VThreadRunner.run(() -> {
1381 long start = millisTime();
1382 synchronized (lock) {
1383 Thread.sleep(1000);
1384 }
1385 expectDuration(start, /*min*/900, /*max*/4000);
1386 });
1387 }
1388
1389 /**
1390 * Test Thread.sleep when pinned and with interrupt status set.
1391 */
1392 @Test
1393 void testSleep9() throws Exception {
1394 VThreadRunner.run(() -> {
1395 Thread me = Thread.currentThread();
1396 me.interrupt();
1397 try {
1398 synchronized (lock) {
1399 Thread.sleep(2000);
1400 }
1401 fail("sleep not interrupted");
1402 } catch (InterruptedException e) {
1403 // expected
1404 assertFalse(me.isInterrupted());
1405 }
1508 /**
1509 * Test inheriting initial value of TCCL through an intermediate virtual thread.
1510 */
1511 @Test
1512 void testContextClassLoader4() throws Exception {
1513 ClassLoader loader = new ClassLoader() { };
1514 Thread t = Thread.currentThread();
1515 ClassLoader savedLoader = t.getContextClassLoader();
1516 t.setContextClassLoader(loader);
1517 try {
1518 VThreadRunner.run(() -> {
1519 VThreadRunner.run(() -> {
1520 assertTrue(Thread.currentThread().getContextClassLoader() == loader);
1521 });
1522 });
1523 } finally {
1524 t.setContextClassLoader(savedLoader);
1525 }
1526 }
1527
1528 /**
1529 * Test Thread.xxxContextClassLoader when thread locals not supported.
1530 */
1531 @Test
1532 void testContextClassLoader5() throws Exception {
1533 ClassLoader scl = ClassLoader.getSystemClassLoader();
1534 ClassLoader loader = new ClassLoader() { };
1535 VThreadRunner.run(VThreadRunner.NO_THREAD_LOCALS, () -> {
1536 Thread t = Thread.currentThread();
1537 assertTrue(t.getContextClassLoader() == scl);
1538 assertThrows(UnsupportedOperationException.class,
1539 () -> t.setContextClassLoader(loader));
1540 assertTrue(t.getContextClassLoader() == scl);
1541 });
1542 }
1543
1544 /**
1545 * Test Thread.xxxContextClassLoader when thread does not inherit the
1546 * initial value of inheritable thread locals.
1547 */
1548 @Test
1549 void testContextClassLoader6() throws Exception {
1550 VThreadRunner.run(() -> {
1551 ClassLoader loader = new ClassLoader() { };
1552 Thread.currentThread().setContextClassLoader(loader);
1553 int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
1554 VThreadRunner.run(characteristics, () -> {
1555 Thread t = Thread.currentThread();
1556 assertTrue(t.getContextClassLoader() == ClassLoader.getSystemClassLoader());
1557 t.setContextClassLoader(loader);
1558 assertTrue(t.getContextClassLoader() == loader);
1559 });
1560 });
1561 }
1562
1563 /**
1564 * Test Thread.setUncaughtExceptionHandler.
1565 */
1566 @Test
1567 void testUncaughtExceptionHandler1() throws Exception {
1568 class FooException extends RuntimeException { }
1569 var exception = new AtomicReference<Throwable>();
|
1230
1231 /**
1232 * Tasks that sleep for 1 second.
1233 */
1234 static Stream<ThrowingRunnable> oneSecondSleepers() {
1235 return Stream.of(
1236 () -> Thread.sleep(1000),
1237 () -> Thread.sleep(Duration.ofSeconds(1))
1238 );
1239 }
1240
1241 /**
1242 * Test Thread.sleep duration.
1243 */
1244 @ParameterizedTest
1245 @MethodSource("oneSecondSleepers")
1246 void testSleep3(ThrowingRunnable sleeper) throws Exception {
1247 VThreadRunner.run(() -> {
1248 long start = millisTime();
1249 sleeper.run();
1250 expectDuration(start, /*min*/900, /*max*/20_000);
1251 });
1252 }
1253
1254 /**
1255 * Tasks that sleep for zero or longer duration.
1256 */
1257 static Stream<ThrowingRunnable> sleepers() {
1258 return Stream.of(
1259 () -> Thread.sleep(0),
1260 () -> Thread.sleep(0, 0),
1261 () -> Thread.sleep(1000),
1262 () -> Thread.sleep(1000, 0),
1263 () -> Thread.sleep(Duration.ofMillis(0)),
1264 () -> Thread.sleep(Duration.ofMillis(1000))
1265 );
1266 }
1267
1268 /**
1269 * Test Thread.sleep with interrupt status set.
1270 */
1320 try {
1321 sleeper.run();
1322 fail("sleep was not interrupted");
1323 } catch (InterruptedException e) {
1324 // interrupt status should be cleared
1325 assertFalse(t.isInterrupted());
1326 }
1327 });
1328 }
1329
1330 /**
1331 * Test that Thread.sleep does not disrupt parking permit.
1332 */
1333 @Test
1334 void testSleep6() throws Exception {
1335 VThreadRunner.run(() -> {
1336 LockSupport.unpark(Thread.currentThread());
1337
1338 long start = millisTime();
1339 Thread.sleep(1000);
1340 expectDuration(start, /*min*/900, /*max*/20_000);
1341
1342 // check that parking permit was not consumed
1343 LockSupport.park();
1344 });
1345 }
1346
1347 /**
1348 * Test that Thread.sleep is not disrupted by unparking thread.
1349 */
1350 @Test
1351 void testSleep7() throws Exception {
1352 AtomicReference<Exception> exc = new AtomicReference<>();
1353 var thread = Thread.ofVirtual().start(() -> {
1354 try {
1355 long start = millisTime();
1356 Thread.sleep(1000);
1357 expectDuration(start, /*min*/900, /*max*/20_000);
1358 } catch (Exception e) {
1359 exc.set(e);
1360 }
1361
1362 });
1363 // attempt to disrupt sleep
1364 for (int i = 0; i < 5; i++) {
1365 Thread.sleep(20);
1366 LockSupport.unpark(thread);
1367 }
1368 thread.join();
1369 Exception e = exc.get();
1370 if (e != null) {
1371 throw e;
1372 }
1373 }
1374
1375 /**
1376 * Test Thread.sleep when pinned.
1377 */
1378 @Test
1379 void testSleep8() throws Exception {
1380 VThreadRunner.run(() -> {
1381 long start = millisTime();
1382 synchronized (lock) {
1383 Thread.sleep(1000);
1384 }
1385 expectDuration(start, /*min*/900, /*max*/20_000);
1386 });
1387 }
1388
1389 /**
1390 * Test Thread.sleep when pinned and with interrupt status set.
1391 */
1392 @Test
1393 void testSleep9() throws Exception {
1394 VThreadRunner.run(() -> {
1395 Thread me = Thread.currentThread();
1396 me.interrupt();
1397 try {
1398 synchronized (lock) {
1399 Thread.sleep(2000);
1400 }
1401 fail("sleep not interrupted");
1402 } catch (InterruptedException e) {
1403 // expected
1404 assertFalse(me.isInterrupted());
1405 }
1508 /**
1509 * Test inheriting initial value of TCCL through an intermediate virtual thread.
1510 */
1511 @Test
1512 void testContextClassLoader4() throws Exception {
1513 ClassLoader loader = new ClassLoader() { };
1514 Thread t = Thread.currentThread();
1515 ClassLoader savedLoader = t.getContextClassLoader();
1516 t.setContextClassLoader(loader);
1517 try {
1518 VThreadRunner.run(() -> {
1519 VThreadRunner.run(() -> {
1520 assertTrue(Thread.currentThread().getContextClassLoader() == loader);
1521 });
1522 });
1523 } finally {
1524 t.setContextClassLoader(savedLoader);
1525 }
1526 }
1527
1528 /**
1529 * Test Thread.xxxContextClassLoader when thread does not inherit the
1530 * initial value of inheritable thread locals.
1531 */
1532 @Test
1533 void testContextClassLoader5() throws Exception {
1534 VThreadRunner.run(() -> {
1535 ClassLoader loader = new ClassLoader() { };
1536 Thread.currentThread().setContextClassLoader(loader);
1537 int characteristics = VThreadRunner.NO_INHERIT_THREAD_LOCALS;
1538 VThreadRunner.run(characteristics, () -> {
1539 Thread t = Thread.currentThread();
1540 assertTrue(t.getContextClassLoader() == ClassLoader.getSystemClassLoader());
1541 t.setContextClassLoader(loader);
1542 assertTrue(t.getContextClassLoader() == loader);
1543 });
1544 });
1545 }
1546
1547 /**
1548 * Test Thread.setUncaughtExceptionHandler.
1549 */
1550 @Test
1551 void testUncaughtExceptionHandler1() throws Exception {
1552 class FooException extends RuntimeException { }
1553 var exception = new AtomicReference<Throwable>();
|