Skip to content

Commit 17ae11c

Browse files
committed
Shin-ichiro Hara's ConditionVariable
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@481 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 2996504 commit 17ae11c

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

lib/thread.rb

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ class ThreadError<StandardError
1717
Thread.abort_on_exception = true
1818
end
1919

20+
def Thread.exclusive
21+
begin
22+
Thread.critical = true
23+
r = yield
24+
ensure
25+
Thread.critical = false
26+
end
27+
r
28+
end
29+
2030
class Mutex
2131
def initialize
2232
@waiting = []
@@ -68,39 +78,46 @@ def synchronize
6878
unlock
6979
end
7080
end
81+
82+
def exclusive_unlock
83+
return unless @locked
84+
Thread.exclusive do
85+
t = @waiting.shift
86+
@locked = false
87+
t.wakeup if t
88+
yield
89+
end
90+
self
91+
end
7192
end
7293

7394
class ConditionVariable
7495
def initialize
7596
@waiters = []
76-
@waiters_mutex = Mutex.new
77-
@waiters.taint # enable tainted comunication
78-
self.taint
7997
end
8098

8199
def wait(mutex)
82-
mutex.unlock
83-
@waiters_mutex.synchronize {
100+
mutex.exclusive_unlock do
84101
@waiters.push(Thread.current)
85-
}
86-
Thread.stop
102+
Thread.stop
103+
end
87104
mutex.lock
88105
end
89106

90107
def signal
91-
@waiters_mutex.synchronize {
92-
t = @waiters.shift
93-
t.run if t
94-
}
108+
t = @waiters.shift
109+
t.run if t
95110
end
96111

97112
def broadcast
98-
@waiters_mutex.synchronize {
99-
for t in @waiters
100-
t.run
101-
end
113+
waitors0 = nil
114+
Thread.exclusive do
115+
waiters0 = @waitors.dup
102116
@waiters.clear
103-
}
117+
end
118+
for t in waiters0
119+
t.run
120+
end
104121
end
105122
end
106123

0 commit comments

Comments
 (0)