diff options
author | Samuel Williams <[email protected]> | 2025-06-06 09:38:57 +0900 |
---|---|---|
committer | GitHub <[email protected]> | 2025-06-06 09:38:57 +0900 |
commit | f0cf4dce65ba7bf3dc6787e10b88e08b411e2c92 (patch) | |
tree | b5a85f799d58985d1b3f5d088a2cdf77eed00a03 /test | |
parent | e66ac2a743a03bd1af99c3d56b0ec94edfd423e8 (diff) |
Handle spurious wakeups in `Thread#join`. (#13532)
Notes
Notes:
Merged-By: ioquatix <[email protected]>
Diffstat (limited to 'test')
-rw-r--r-- | test/fiber/scheduler.rb | 2 | ||||
-rw-r--r-- | test/fiber/test_thread.rb | 41 |
2 files changed, 42 insertions, 1 deletions
diff --git a/test/fiber/scheduler.rb b/test/fiber/scheduler.rb index 5782efd0d1..26a807c8c5 100644 --- a/test/fiber/scheduler.rb +++ b/test/fiber/scheduler.rb @@ -126,7 +126,7 @@ class Scheduler end ready.each do |fiber| - fiber.transfer + fiber.transfer if fiber.alive? end end end diff --git a/test/fiber/test_thread.rb b/test/fiber/test_thread.rb index 5e3cc6d0e1..0247f330d9 100644 --- a/test/fiber/test_thread.rb +++ b/test/fiber/test_thread.rb @@ -90,6 +90,47 @@ class TestFiberThread < Test::Unit::TestCase assert_equal :done, thread.value end + def test_spurious_unblock_during_thread_join + ready = Thread::Queue.new + + target_thread = Thread.new do + ready.pop + :success + end + + Thread.pass until target_thread.status == "sleep" + + result = nil + + thread = Thread.new do + scheduler = Scheduler.new + Fiber.set_scheduler scheduler + + # Create a fiber that will join a long-running thread: + joining_fiber = Fiber.schedule do + result = target_thread.value + end + + # Create another fiber that spuriously unblocks the joining fiber: + Fiber.schedule do + # This interrupts the join in joining_fiber: + scheduler.unblock(:spurious_wakeup, joining_fiber) + + # This allows the unblock to be processed: + sleep(0) + + # This allows the target thread to finish: + ready.push(:done) + end + + scheduler.run + end + + thread.join + + assert_equal :success, result + end + def test_broken_unblock thread = Thread.new do Thread.current.report_on_exception = false |