Class: VCAP::Concurrency::AtomicVar

Inherits:
Object
  • Object
show all
Defined in:
lib/vcap/concurrency/atomic_var.rb

Overview

A variable that can be queried and updated atomically.

Instance Method Summary collapse

Constructor Details

#initialize(initial_value = nil) ⇒ AtomicVar

Returns a new instance of AtomicVar.



10
11
12
13
14
# File 'lib/vcap/concurrency/atomic_var.rb', line 10

def initialize(initial_value = nil)
  @value = initial_value
  @lock  = Mutex.new
  @cond  = ConditionVariable.new
end

Instance Method Details

#mutate(&blk) ⇒ Object

Allows the caller to atomically mutate the current value. The new value will be whatever the supplied block evalutes to.

Parameters:

  • blk (Block)

    The block to execute while the lock is held. The current value will be passed as the only argument to the block.

Returns:

  • (Object)

    The result of the block (also the new value bound to the var).



59
60
61
62
63
64
65
66
67
# File 'lib/vcap/concurrency/atomic_var.rb', line 59

def mutate(&blk)
  @lock.synchronize do
    @value = blk.call(@value)

    @cond.broadcast

    @value
  end
end

#valueObject

Returns The value bound to this variable.

Returns:

  • (Object)

    The value bound to this variable.



17
18
19
# File 'lib/vcap/concurrency/atomic_var.rb', line 17

def value
  @lock.synchronize { @value }
end

#value=(new_value) ⇒ Object



46
47
48
# File 'lib/vcap/concurrency/atomic_var.rb', line 46

def value=(new_value)
  mutate { |v| new_value }
end

#wait_value_changed(last_value) ⇒ Object

Blocks the calling thread until the current value is different from the supplied value.

Parameters:

  • last_value (Object)

    This method will return once the current value no longer equals last_value.

Returns:

  • (Object)

    The new value



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/vcap/concurrency/atomic_var.rb', line 28

def wait_value_changed(last_value)
  done = false
  result = nil

  while !done
    @lock.synchronize do
      if last_value == @value
        @cond.wait(@lock)
      else
        done = true
        result = @value
      end
    end
  end

  result
end