class Empathy::EM::Mutex

An Empathy equivalent to ::Mutex

Public Class Methods

new() click to toggle source
# File lib/empathy/em/mutex.rb, line 7
def initialize()
  @waiters = []
end

Public Instance Methods

lock() click to toggle source

Like ::Mutex#lock, except allows reentrant locks @return [Mutex] self

# File lib/empathy/em/mutex.rb, line 13
def lock()
  em_thread = Thread.current
  @waiters << em_thread
  #The lock allows reentry but requires matching unlocks
  em_thread.send(:yield_sleep) unless @waiters.first == em_thread
  # Now em_thread has the lock, make sure it is released if the em_thread thread dies
  em_thread.ensure_hook(self) { release() unless waiters.empty? || waiters.first != em_thread }
  self
end
locked?() click to toggle source

Like ::Mutex#locked? @return [true,false]

# File lib/empathy/em/mutex.rb, line 35
def locked?
  !@waiters.empty? && @waiters.first.alive?
end
sleep(timeout=nil) click to toggle source

Like ::Mutex#sleep @param [Numeric] timeout @return [Fixnum]

# File lib/empathy/em/mutex.rb, line 62
def sleep(timeout=nil)
  unlock
  begin
    if timeout then Kernel.sleep(timeout) else Kernel.sleep() end
  ensure
    lock
  end
end
synchronize() { || ... } click to toggle source

Like ::Mutex#synchronize @return the result of the block

# File lib/empathy/em/mutex.rb, line 52
def synchronize(&block)
  lock
  yield
ensure
  unlock
end
try_lock() click to toggle source

Like ::Mutex#try_lock @return [true,false]

# File lib/empathy/em/mutex.rb, line 41
def try_lock
  if locked?
    false
  else
    lock
    true
  end
end
unlock() click to toggle source

Like ::Mutex#unlock @return [Mutex] self @raise [FiberError] if not owner of the mutex

# File lib/empathy/em/mutex.rb, line 26
def unlock()
  em_thread = Thread.current
  raise FiberError, "not owner" unless @waiters.first == em_thread
  release()
  self
end

Private Instance Methods

release() click to toggle source
# File lib/empathy/em/mutex.rb, line 76
def release()
  # release the current lock holder, and clear the em_thread death hook
  waiters.shift.ensure_hook(self)

  ::EM.next_tick do
    waiters.shift until waiters.empty? || waiters.first.alive?
    waiters.first.send(:wake_resume) unless waiters.empty?
  end
end
waiters() click to toggle source
# File lib/empathy/em/mutex.rb, line 72
def waiters
  @waiters
end