class Variable
Lightweight concurrency variables
Constants
- EMPTY
- TIMEOUT
Public Class Methods
Initialize object
@param [Object] value
the initial value
@return [undefined]
# File lib/variable.rb, line 83 def initialize(condition_variable:, mutex:, value: EMPTY) @full = condition_variable.new @mutex = mutex.new @value = value end
Public Instance Methods
Read value, block on empty
@return [Object]
the variable value
# File lib/variable.rb, line 122 def read synchronize do wait_full @value end end
Take value, block on empty
@return [Object]
# File lib/variable.rb, line 92 def take synchronize do wait_full perform_take end end
Take value, with timeout
@param [Float] Timeout
@return [Result::Timeout]
in case take resulted in a timeout
@return [Result::Value]
in case take resulted in a value
# File lib/variable.rb, line 108 def take_timeout(timeout) synchronize do if wait_timeout(@full, timeout, &method(:full?)) Result::Timeout.new else Result::Value.new(perform_take) end end end
Try put value into the variable, non blocking
@param [Object] value
@return [self]
# File lib/variable.rb, line 134 def try_put(value) synchronize do perform_put(value) if empty? end self end
Execute block with value, blocking
@yield [Object]
@return [Object]
the blocks return value
# File lib/variable.rb, line 148 def with synchronize do wait_full yield @value end end
Private Instance Methods
Test if state is empty
@return [Boolean]
# File lib/variable.rb, line 214 def empty? @value.equal?(EMPTY) end
Test if state is full
@return [Boolean]
# File lib/variable.rb, line 207 def full? !empty? end
Perform the put
@param [Object] value
# File lib/variable.rb, line 160 def perform_put(value) (@value = value).tap { @full.signal } end
Execute block under mutex
@return [self]
# File lib/variable.rb, line 167 def synchronize(&block) @mutex.synchronize(&block) end
Wait for block predicate
@param [ConditionVariable] event
@return [undefined]
# File lib/variable.rb, line 176 def wait(event) event.wait(@mutex) until yield end
Wait till mvar is full
@return [undefined]
# File lib/variable.rb, line 200 def wait_full wait(@full, &method(:full?)) end
Wait with timeout for block predicate
@param [ConditionVariable] event
@return [Boolean]
if wait was terminated due a timeout
@return [undefined]
otherwise
# File lib/variable.rb, line 189 def wait_timeout(event, timeout) loop do break true if timeout <= 0 break if yield timeout -= Timer.elapsed { event.wait(@mutex, timeout) } end end