@@ -327,21 +327,41 @@ private final class WorkerThread(
327327 }
328328 }
329329
330- def parkUntilNextSleeper (): Unit = {
331- if (! isInterrupted()) {
330+ // returns true if timed out, false if unparked
331+ def parkUntilNextSleeper (): Boolean = {
332+ while (! done.get()) {
332333 val now = System .nanoTime()
333334 val head = sleepersQueue.head()
334335 val nanos = head.triggerTime - now
336+
337+ // System.err.println(s"parking for $nanos nanos")
335338 LockSupport .parkNanos(pool, nanos)
336339
337- if (parked.getAndSet(false )) {
338- pool.doneSleeping()
340+ if (isInterrupted()) {
341+ pool.shutdown()
342+ } else {
343+ if (parked.get()) {
344+ // we were either awakened spuriously, or we timed out
345+
346+ if (head.triggerTime - System .nanoTime() <= 0 ) {
347+ // we timed out
348+ if (parked.getAndSet(false )) {
349+ pool.doneSleeping()
350+ }
351+
352+ return true
353+ }
354+ } else {
355+ // we were awakened
356+ return false
357+ }
339358 }
340359 }
360+
361+ false
341362 }
342363
343364 while (! done.get()) {
344-
345365 if (blocking) {
346366 // The worker thread was blocked before. It is no longer part of the
347367 // core pool and needs to be cached.
@@ -394,25 +414,6 @@ private final class WorkerThread(
394414
395415 val sleepers = sleepersQueue
396416
397- if (sleepers.nonEmpty) {
398- val now = System .nanoTime()
399-
400- var cont = true
401- while (cont) {
402- val head = sleepers.head()
403-
404- if (head.triggerTime - now <= 0 ) {
405- if (head.get()) {
406- head.callback(RightUnit )
407- }
408- sleepers.popHead()
409- cont = sleepers.nonEmpty
410- } else {
411- cont = false
412- }
413- }
414- }
415-
416417 ((state & ExternalQueueTicksMask ): @ switch) match {
417418 case 0 =>
418419 if (pool.blockedThreadDetectionEnabled) {
@@ -538,13 +539,20 @@ private final class WorkerThread(
538539 // Park the thread.
539540 if (sleepers.isEmpty) {
540541 parkLoop()
542+
543+ // After the worker thread has been unparked, look for work in the
544+ // external queue.
545+ state = 3
541546 } else {
542- parkUntilNextSleeper()
547+ if (parkUntilNextSleeper()) {
548+ // we made it to the end of our sleeping, so go straight to local queue stuff
549+ pool.transitionWorkerFromSearching(rnd)
550+ state = 4
551+ } else {
552+ // we were interrupted, look for more work in the external queue
553+ state = 3
554+ }
543555 }
544-
545- // After the worker thread has been unparked, look for work in the
546- // external queue.
547- state = 3
548556 }
549557 }
550558
@@ -584,13 +592,20 @@ private final class WorkerThread(
584592 // Park the thread.
585593 if (sleepers.isEmpty) {
586594 parkLoop()
595+
596+ // After the worker thread has been unparked, look for work in the
597+ // external queue.
598+ state = 3
587599 } else {
588- parkUntilNextSleeper()
600+ if (parkUntilNextSleeper()) {
601+ // we made it to the end of our sleeping, so go straight to local queue stuff
602+ pool.transitionWorkerFromSearching(rnd)
603+ state = 4
604+ } else {
605+ // we were interrupted, look for more work in the external queue
606+ state = 3
607+ }
589608 }
590-
591- // After the worker thread has been unparked, look for work in the
592- // external queue.
593- state = 3
594609 }
595610
596611 case 3 =>
@@ -647,6 +662,26 @@ private final class WorkerThread(
647662 }
648663
649664 case _ =>
665+ if (sleepers.nonEmpty) {
666+ val now = System .nanoTime()
667+
668+ var cont = true
669+ while (cont) {
670+ val head = sleepers.head()
671+
672+ if (head.triggerTime - now <= 0 ) {
673+ if (head.get()) {
674+ // System.err.println(s"dequeued with state = $state; sleepers = $sleepers")
675+ head.callback(RightUnit )
676+ }
677+ sleepers.popHead()
678+ cont = sleepers.nonEmpty
679+ } else {
680+ cont = false
681+ }
682+ }
683+ }
684+
650685 // Check the queue bypass reference before dequeueing from the local
651686 // queue.
652687 val fiber = if (cedeBypass eq null ) {
0 commit comments