@@ -277,6 +277,40 @@ private static void signalNextIfShared(Node h) {
277
277
}
278
278
}
279
279
280
+ /**
281
+ * Repeatedly invokes acquire, if its execution throws an Error or a Runtime Exception,
282
+ * using an Unsafe.park-based backoff
283
+ * @param node which to reacquire
284
+ * @param arg the acquire argument
285
+ */
286
+ private final void reacquire (Node node , long arg ) {
287
+ try {
288
+ acquire (node , arg , false , false , false , 0L );
289
+ } catch (Error | RuntimeException firstEx ) {
290
+ // While we currently do not emit an JFR events in this situation, mainly
291
+ // because the conditions under which this happens are such that it
292
+ // cannot be presumed to be possible to actually allocate an event, and
293
+ // using a preconstructed one would have limited value in serviceability.
294
+ // Having said that, the following place would be the more appropriate
295
+ // place to put such logic:
296
+ // emit JFR event
297
+
298
+ for (long nanos = 1L ;;) {
299
+ U .park (false , nanos ); // must use Unsafe park to sleep
300
+ if (nanos < 1L << 30 ) // max about 1 second
301
+ nanos <<= 1 ;
302
+
303
+ try {
304
+ acquire (node , arg , false , false , false , 0L );
305
+ } catch (Error | RuntimeException ignored ) {
306
+ continue ;
307
+ }
308
+
309
+ throw firstEx ;
310
+ }
311
+ }
312
+ }
313
+
280
314
/**
281
315
* Main acquire method, invoked by all exported acquire methods.
282
316
*
@@ -1299,7 +1333,7 @@ else if ((node.status & COND) != 0) {
1299
1333
}
1300
1334
LockSupport .setCurrentBlocker (null );
1301
1335
node .clearStatus ();
1302
- acquire (node , savedState , false , false , false , 0L );
1336
+ reacquire (node , savedState );
1303
1337
if (interrupted )
1304
1338
Thread .currentThread ().interrupt ();
1305
1339
}
@@ -1346,7 +1380,7 @@ public final void await() throws InterruptedException {
1346
1380
}
1347
1381
LockSupport .setCurrentBlocker (null );
1348
1382
node .clearStatus ();
1349
- acquire (node , savedState , false , false , false , 0L );
1383
+ reacquire (node , savedState );
1350
1384
if (interrupted ) {
1351
1385
if (cancelled ) {
1352
1386
unlinkCancelledWaiters (node );
@@ -1389,7 +1423,7 @@ public final long awaitNanos(long nanosTimeout)
1389
1423
LockSupport .parkNanos (this , nanos );
1390
1424
}
1391
1425
node .clearStatus ();
1392
- acquire (node , savedState , false , false , false , 0L );
1426
+ reacquire (node , savedState );
1393
1427
if (cancelled ) {
1394
1428
unlinkCancelledWaiters (node );
1395
1429
if (interrupted )
@@ -1433,7 +1467,7 @@ public final boolean awaitUntil(Date deadline)
1433
1467
LockSupport .parkUntil (this , abstime );
1434
1468
}
1435
1469
node .clearStatus ();
1436
- acquire (node , savedState , false , false , false , 0L );
1470
+ reacquire (node , savedState );
1437
1471
if (cancelled ) {
1438
1472
unlinkCancelledWaiters (node );
1439
1473
if (interrupted )
@@ -1478,7 +1512,7 @@ public final boolean await(long time, TimeUnit unit)
1478
1512
LockSupport .parkNanos (this , nanos );
1479
1513
}
1480
1514
node .clearStatus ();
1481
- acquire (node , savedState , false , false , false , 0L );
1515
+ reacquire (node , savedState );
1482
1516
if (cancelled ) {
1483
1517
unlinkCancelledWaiters (node );
1484
1518
if (interrupted )
0 commit comments