summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorshugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-06-04 09:49:23 +0000
committershugo <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-06-04 09:49:23 +0000
commit17ae11ca25d210da8c7deeeee0f03fd1a09ee0b2 (patch)
tree15ac03d63068d288dce8a237c27edeeec51ad95a /lib
parent2996504623d83ecb5620e7660e871a98aa9771e4 (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
Diffstat (limited to 'lib')
-rw-r--r--lib/thread.rb49
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/thread.rb b/lib/thread.rb
index 936768f..baa248e 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