diff options
author | shugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-06-04 09:49:23 +0000 |
---|---|---|
committer | shugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 1999-06-04 09:49:23 +0000 |
commit | 17ae11ca25d210da8c7deeeee0f03fd1a09ee0b2 (patch) | |
tree | 15ac03d63068d288dce8a237c27edeeec51ad95a | |
parent | 2996504623d83ecb5620e7660e871a98aa9771e4 (diff) |
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
-rw-r--r-- | lib/thread.rb | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/thread.rb b/lib/thread.rb index 936768fa9b..baa248e927 100644 --- a/lib/thread.rb +++ b/lib/thread.rb @@ -17,6 +17,16 @@ if $DEBUG Thread.abort_on_exception = true end +def Thread.exclusive + begin + Thread.critical = true + r = yield + ensure + Thread.critical = false + end + r +end + class Mutex def initialize @waiting = [] @@ -68,39 +78,46 @@ class Mutex unlock end end + + def exclusive_unlock + return unless @locked + Thread.exclusive do + t = @waiting.shift + @locked = false + t.wakeup if t + yield + end + self + end end class ConditionVariable def initialize @waiters = [] - @waiters_mutex = Mutex.new - @waiters.taint # enable tainted comunication - self.taint end def wait(mutex) - mutex.unlock - @waiters_mutex.synchronize { + mutex.exclusive_unlock do @waiters.push(Thread.current) - } - Thread.stop + Thread.stop + end mutex.lock end def signal - @waiters_mutex.synchronize { - t = @waiters.shift - t.run if t - } + t = @waiters.shift + t.run if t end def broadcast - @waiters_mutex.synchronize { - for t in @waiters - t.run - end + waitors0 = nil + Thread.exclusive do + waiters0 = @waitors.dup @waiters.clear - } + end + for t in waiters0 + t.run + end end end |