summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorSamuel Williams <[email protected]>2025-06-06 09:38:57 +0900
committerGitHub <[email protected]>2025-06-06 09:38:57 +0900
commitf0cf4dce65ba7bf3dc6787e10b88e08b411e2c92 (patch)
treeb5a85f799d58985d1b3f5d088a2cdf77eed00a03 /test
parente66ac2a743a03bd1af99c3d56b0ec94edfd423e8 (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.rb2
-rw-r--r--test/fiber/test_thread.rb41
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