Class: Semaphore

Inherits:
Object
  • Object
show all
Defined in:
lib/quartz_torrent/semaphore.rb

Overview

Implements a counting semaphore.

Instance Method Summary collapse

Constructor Details

#initialize(count = 0) ⇒ Semaphore

Create a new semaphore initialized to the specified count.



5
6
7
8
9
# File 'lib/quartz_torrent/semaphore.rb', line 5

def initialize(count = 0)
  @mutex = Mutex.new
  @count = count
  @sleeping = []
end

Instance Method Details

#countObject

Testing method.



53
54
55
# File 'lib/quartz_torrent/semaphore.rb', line 53

def count
  @count
end

#signalObject

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



40
41
42
43
44
45
46
47
48
49
50
# 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) ⇒ Object

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.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 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