class PriorityMutex

Public Class Methods

new() click to toggle source
# File lib/priority_mutex.rb, line 35
def initialize
  @pq = PQueue.new
  @pq_mutex = Mutex.new
  @resource_active = false
end

Public Instance Methods

locked?() click to toggle source
# File lib/priority_mutex.rb, line 50
def locked?
  @resource_active || @pq.size > 0
end
synchronize(priority = 0) { || ... } click to toggle source
# File lib/priority_mutex.rb, line 41
def synchronize(priority = 0)
  wait_for_resource_if_necessary(priority)
  begin
    yield
  ensure
    release_resource rescue nil
  end
end

Private Instance Methods

release_resource() click to toggle source
# File lib/priority_mutex.rb, line 78
def release_resource
  @pq_mutex.synchronize do
    if next_waiter = @pq.pop
      next_waiter.resume
    else
      @resource_active = false
    end
  end
end
wait_for_resource_if_necessary(priority) click to toggle source
# File lib/priority_mutex.rb, line 56
def wait_for_resource_if_necessary(priority)
  waiter = nil

  @pq_mutex.synchronize do
    if @resource_active
      # So we'll need to wait, waiting happens _outside_ of this
      # synchronization block to ensure that
      waiter = Waiter.new(priority)
      @pq.push(waiter)

    else
      @resource_active = true

    end
  end

  if waiter
    waiter.wait
    @pq_mutex.synchronize { @resource_active = true }
  end
end