class Semaphore

Implements a counting semaphore.

Public Class Methods

new(count = 0) click to toggle source

Create a new semaphore initialized to the specified count.

# File lib/quartz_torrent/semaphore.rb, line 5
def initialize(count = 0)
  @mutex = Mutex.new
  @count = count
  @sleeping = []
end

Public Instance Methods

count() click to toggle source

Testing method.

# File lib/quartz_torrent/semaphore.rb, line 53
def count
  @count
end
signal() click to toggle source

Signal the semaphore. If the count is below zero the waiting threads are woken.

# File lib/quartz_torrent/semaphore.rb, line 40
def signal
  c = nil
  @mutex.synchronize do
    c = @count
    @count += 1
    if c < 0 
      t = @sleeping.shift
      t.wakeup if t
    end
  end
end
wait(timeout = nil) click to toggle source

Wait on the semaphore. If the count zero or below, the calling thread blocks. Optionally a timeout in seconds can be specified. This method returns true if the wait ended because of a signal, and false if it ended because of a timeout.

# File lib/quartz_torrent/semaphore.rb, line 14
def wait(timeout = nil)
  result = true
  c = nil
  @mutex.synchronize do
    @count -= 1
    if @count < 0
      @sleeping.push Thread.current
      @mutex.sleep(timeout)
    end
  end
  if timeout
    # If we had a timeout we may have woken due to it expiring rather than
    # due to signal being called. In that case we need to remove ourself from the sleepers.
    @mutex.synchronize do
      i = @sleeping.index(Thread.current)
      if i
        @count += 1
        @sleeping.delete_at(i)
        result = false
      end
    end
  end
  result
end