class Atomic

def compare_and_set(old_value, new_value)

def compare_and_set(old_value, new_value)
  return false unless @mutex.try_lock
  begin
    return false unless @value.equal? old_value
    @value = new_value
  ensure
    @mutex.unlock
  end
  true
end

def compare_and_set(expected, new)

def compare_and_set(expected, new)
  if expected.kind_of? Numeric
    while true
      old = get
      
      return false unless old.kind_of? Numeric
      
      return false unless old == expected
      
      result = _compare_and_set(old, new)
      return result if result
    end
  else
    _compare_and_set(expected, new)
  end
end

def get

def get
  @mutex.synchronize { @value }
end

def get_and_set(new_value)

def get_and_set(new_value)
  @mutex.synchronize do
    old_value = @value
    @value = new_value
    old_value
  end
end

def initialize(value = nil)

:nodoc: all
Portable/generic (but not very memory or scheduling-efficient) fallback
def initialize(value = nil)
  @mutex = Mutex.new
  @value = value
end

def set(new_value)

def set(new_value)
  @mutex.synchronize { @value = new_value }
end

def try_update

def try_update
  old_value = @ref.get
  new_value = yield old_value
  unless @ref.compare_and_set(old_value, new_value)
    if $VERBOSE
      raise ConcurrentUpdateError, "Update failed"
    else
      raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE
    end
  end
  new_value
end

def try_update

def try_update
  old_value = get
  new_value = yield old_value
  unless compare_and_set(old_value, new_value)
    if $VERBOSE
      raise ConcurrentUpdateError, "Update failed"
    else
      raise ConcurrentUpdateError, "Update failed", ConcurrentUpdateError::CONC_UP_ERR_BACKTRACE
    end
  end
  new_value
end

def update

during the block's execution.
with the block's result. May retry if the value changes
Pass the current value to the given block, replacing it
def update
  true until @ref.compare_and_set(old_value = @ref.get, new_value = yield(old_value))
  new_value
end

def update

during the block's execution.
with the block's result. May retry if the value changes
Pass the current value to the given block, replacing it
def update
  true until compare_and_set(old_value = get, new_value = yield(old_value))
  new_value
end