Sha256: ed0ae66255df4913a42e80d26f3c52a65106fd390948a46bb4d934826c49608c

Contents?: true

Size: 1.55 KB

Versions: 1

Compression:

Stored size: 1.55 KB

Contents

require "thread"

module VCAP
  module Concurrency
  end
end

# A variable that can be queried and updated atomically.
class VCAP::Concurrency::AtomicVar
  def initialize(initial_value = nil)
    @value = initial_value
    @lock  = Mutex.new
    @cond  = ConditionVariable.new
  end

  # @return [Object]  The value bound to this variable.
  def value
    @lock.synchronize { @value }
  end

  # Blocks the calling thread until the current value is different from the
  # supplied value.
  #
  # @param  [Object]  last_value  This method will return once the current
  #                               value no longer equals last_value.
  #
  # @return [Object]  The new value
  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

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

  # Allows the caller to atomically mutate the current value. The new value
  # will be whatever the supplied block evalutes to.
  #
  # @param [Block]  blk  The block to execute while the lock is held. The
  #                      current value will be passed as the only argument to
  #                      the block.
  #
  # @return [Object]     The result of the block (also the new value bound to
  #                      the var).
  def mutate(&blk)
    @lock.synchronize do
      @value = blk.call(@value)

      @cond.broadcast

      @value
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
vcap-concurrency-0.1.0 lib/vcap/concurrency/atomic_var.rb