forked from riannucci/scrapon
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemaphore.rb
executable file
·42 lines (34 loc) · 870 Bytes
/
semaphore.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/usr/bin/env ruby-local-exec
#
# $Id: semaphore.rb,v 1.2 2003/03/15 20:10:10 fukumoto Exp $
# $Id: semaphore.rb,v 1.3 2012/01/20 19:39:10 [email protected] Exp $
# * Updated to ruby 1.9.3 compatibility.
# * Fixed some races.
# * Removed unnecessary aliases.
#
class CountingSemaphore
def initialize(counter = 0)
@counter = counter
@waiting_list = []
@lock = Mutex.new
end
def down
added = nil
@lock.synchronize { added = @waiting_list.push(Thread.current) if (@counter -= 1) < 0 }
Thread.stop if added
self
end
def up
removed = nil
@lock.synchronize { removed = @waiting_list.shift if (@counter += 1) <= 0 }
# This can only throw "thread killed", and so there's no point in retry'ing
removed.wakeup if removed rescue nil
self
end
def synchronize
down
yield
ensure
up
end
end