class Rbgo::RWMutex

Public Class Methods

new() click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 7
def initialize
  @lock_count = Hash.new(0)
  @mutex      = ReentrantMutex.new
  @cond       = ConditionVariable.new
  @status     = :unlocked
end

Public Instance Methods

locked?() click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 20
def locked?
  @mutex.synchronize do
    if @lock_count.empty?
      return false
    else
      return true
    end
  end
end
owned?() click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 14
def owned?
  @mutex.synchronize do
    @lock_count.key? Thread.current
  end
end
synchronize_r() { || ... } click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 30
def synchronize_r
  raise ThreadError, 'Must be called with a block' unless block_given?

  begin
    lock_r
    yield
  ensure
    unlock
  end
end
synchronize_w() { || ... } click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 41
def synchronize_w
  raise ThreadError, 'Must be called with a block' unless block_given?

  begin
    lock_w
    yield
  ensure
    unlock
  end
end

Private Instance Methods

lock_r() click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 54
def lock_r
  @mutex.synchronize do
    case @status
    when :locked_for_write
      until @status == :unlocked || @status == :locked_for_read || owned?
        @cond.wait(@mutex)
      end
    end
    tmp_status                  = @status
    @status                     = :locked_for_read
    @lock_count[Thread.current] += 1
    if owned? && tmp_status == :locked_for_write
      @cond.broadcast
    end
    return self
  end
end
lock_w() click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 72
def lock_w
  @mutex.synchronize do
    until @status == :unlocked || (owned? && @status == :locked_for_write)
      @cond.wait(@mutex)
    end
    @status                     = :locked_for_write
    @lock_count[Thread.current] += 1
    return self
  end
end
unlock() click to toggle source
# File lib/rbgo/reentrant_rw_mutex.rb, line 83
def unlock
  @mutex.synchronize do
    if owned?
      @lock_count[Thread.current] -= 1
      @lock_count.delete(Thread.current) if @lock_count[Thread.current] == 0
      if @lock_count.empty?
        @status = :unlocked
        @cond.broadcast
      end
    end
  end
end