From 2100f70119e051cca9a228e4be60069f83370b90 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 7 Dec 2023 14:49:38 +0100 Subject: [PATCH] Loop around ConditionVariable#wait in ReentrantReadWriteLock * To workaround spurious wakeups in CRuby: https://bugs.ruby-lang.org/issues/20047 --- .../concurrent/atomic/reentrant_read_write_lock.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb b/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb index 6d72a3a09..bde6c9784 100644 --- a/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb +++ b/lib/concurrent-ruby/concurrent/atomic/reentrant_read_write_lock.rb @@ -179,7 +179,7 @@ def acquire_read_lock if waiting_or_running_writer?(c) # Before going to sleep, check again with the ReadQueue mutex held @ReadQueue.synchronize do - @ReadQueue.ns_wait if waiting_or_running_writer? + @ReadQueue.ns_wait while waiting_or_running_writer? end # Note: the above 'synchronize' block could have used #wait_until, # but that waits repeatedly in a loop, checking the wait condition @@ -194,7 +194,7 @@ def acquire_read_lock c = @Counter.value if running_writer?(c) @ReadQueue.synchronize do - @ReadQueue.ns_wait if running_writer? + @ReadQueue.ns_wait while running_writer? end elsif @Counter.compare_and_set(c, c+1) @HeldCount.value = held + 1 @@ -282,7 +282,7 @@ def acquire_write_lock # So we have to do another check inside the synchronized section # If a writer OR another reader is running, then go to sleep c = @Counter.value - @WriteQueue.ns_wait if running_writer?(c) || running_readers(c) != held + @WriteQueue.ns_wait while running_writer?(c) || running_readers(c) != held end # Note: if you are thinking of replacing the above 'synchronize' block # with #wait_until, read the comment in #acquire_read_lock first!