Class: AtomicRuby::AtomicConditionVariable
- Inherits:
-
Object
- Object
- AtomicRuby::AtomicConditionVariable
- Defined in:
- lib/atomic-ruby/atomic_condition_variable.rb,
ext/atomic_ruby/atomic_ruby.c
Overview
This class is NOT Ractor-safe as it parks Thread references,
which cannot be shared across ractors.
Provides lock-free wait/signal coordination using atomic operations.
AtomicConditionVariable lets one or more threads park until another
thread signals them, without the paired Mutex that Ruby's
ConditionVariable requires.
Waiters supply a predicate that is checked again after registration, preventing signals sent after a relevant state change from being lost.
Defined Under Namespace
Classes: Waiter
Instance Method Summary collapse
-
#broadcast ⇒ Integer
Wakes every parked waiter.
-
#initialize ⇒ AtomicConditionVariable
constructor
Creates a new condition variable with no parked threads.
-
#signal ⇒ true, false
Wakes one parked waiter, or no-ops if none are parked.
-
#wait ⇒ untyped
Blocks until the given block returns a truthy value, then returns that value.
-
#waiter_count ⇒ Integer
Returns the number of currently parked waiters.
Constructor Details
#initialize ⇒ AtomicConditionVariable
Creates a new condition variable with no parked threads.
43 44 45 |
# File 'lib/atomic-ruby/atomic_condition_variable.rb', line 43 def initialize _initialize end |
Instance Method Details
#broadcast ⇒ Integer
Wakes every parked waiter.
90 91 92 93 94 |
# File 'lib/atomic-ruby/atomic_condition_variable.rb', line 90 def broadcast threads = _drain_threads threads.each { |thread| thread.wakeup rescue nil } threads.size end |
#signal ⇒ true, false
Wakes one parked waiter, or no-ops if none are parked.
73 74 75 76 77 78 79 |
# File 'lib/atomic-ruby/atomic_condition_variable.rb', line 73 def signal thread = _shift_thread return false unless thread thread.wakeup rescue nil true end |
#wait ⇒ untyped
Blocks until the given block returns a truthy value, then returns that value.
The block may run more than once and may run concurrently with a signalling thread. Rechecking it after registration prevents lost wakeups. Interrupted waits are unregistered before the exception is propagated.
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/atomic-ruby/atomic_condition_variable.rb', line 120 def wait result = yield return result if result self_thread = Thread.current loop do Thread.handle_interrupt(Exception => :never) do waiter = _add_waiter(self_thread) begin Thread.handle_interrupt(Exception => :immediate) do result = yield return result if result Thread.stop end ensure _remove_waiter(waiter) end end end end |
#waiter_count ⇒ Integer
Returns the number of currently parked waiters.
This operation is atomic and thread-safe. The returned value reflects the state at the time of the call, but may change immediately after in concurrent environments.
60 61 62 |
# File 'lib/atomic-ruby/atomic_condition_variable.rb', line 60 def waiter_count _waiter_count end |