1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* lib/monitor.rb: rewritten using Mutex/ConditionVariable.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11843 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shugo 2007-02-24 06:15:04 +00:00
parent 61d521117a
commit 33a9e63ad9
2 changed files with 36 additions and 92 deletions

View file

@ -1,3 +1,7 @@
Sat Feb 24 15:14:02 2007 Shugo Maeda <shugo@ruby-lang.org>
* lib/monitor.rb: rewritten using Mutex/ConditionVariable.
Sat Feb 24 13:25:32 2007 Koichi Sasada <ko1@atdot.net> Sat Feb 24 13:25:32 2007 Koichi Sasada <ko1@atdot.net>
* lib/soap/mapping/factory.rb: catch up with spec changes (return * lib/soap/mapping/factory.rb: catch up with spec changes (return

View file

@ -88,31 +88,17 @@ module MonitorMixin
class Timeout < Exception; end class Timeout < Exception; end
def wait(timeout = nil) def wait(timeout = nil)
if timeout
raise NotImplementedError, "timeout is not implemented yet"
end
@monitor.funcall(:mon_check_owner) @monitor.funcall(:mon_check_owner)
timer = create_timer(timeout) count = @monitor.funcall(:mon_exit_for_cond)
count = nil begin
@cond.wait(@monitor.instance_variable_get("@mon_mutex"))
@mutex.synchronize{ return true
count = @monitor.funcall(:mon_exit_for_cond) ensure
@waiters.push(Thread.current)
begin
@mutex.sleep
return true
rescue Timeout
return false
end
}
ensure
@mutex.synchronize {
if timer && timer.alive?
Thread.kill(timer)
end
if @waiters.include?(Thread.current) # interrupted?
@waiters.delete(Thread.current)
end
@monitor.funcall(:mon_enter_for_cond, count) @monitor.funcall(:mon_enter_for_cond, count)
} end
end end
def wait_while def wait_while
@ -129,47 +115,23 @@ module MonitorMixin
def signal def signal
@monitor.funcall(:mon_check_owner) @monitor.funcall(:mon_check_owner)
@mutex.synchronize { @cond.signal
t = @waiters.shift
t.wakeup if t
}
Thread.pass
end end
def broadcast def broadcast
@monitor.funcall(:mon_check_owner) @monitor.funcall(:mon_check_owner)
@mutex.synchronize { @cond.broadcast
for t in @waiters
t.wakeup
end
@waiters.clear
}
Thread.pass
end end
def count_waiters def count_waiters
return @waiters.length raise NotImplementedError
end end
private private
def initialize(monitor) def initialize(monitor)
@monitor = monitor @monitor = monitor
@waiters = [] @cond = ::ConditionVariable.new
@mutex = Mutex.new
end
def create_timer(timeout)
if timeout
waiter = Thread.current
return Thread.start {
Thread.pass
sleep(timeout)
waiter.raise(Timeout.new)
}
else
return nil
end
end end
end end
@ -182,17 +144,14 @@ module MonitorMixin
# Attempts to enter exclusive section. Returns +false+ if lock fails. # Attempts to enter exclusive section. Returns +false+ if lock fails.
# #
def mon_try_enter def mon_try_enter
result = false if @mon_owner != Thread.current
@mon_mutex.synchronize { unless @mon_owner.trylock
if @mon_owner.nil? return false
@mon_owner = Thread.current
end end
if @mon_owner == Thread.current @mon_owner = Thread.current
@mon_count += 1 end
result = true @mon_count += 1
end return true
}
return result
end end
# For backward compatibility # For backward compatibility
alias try_mon_enter mon_try_enter alias try_mon_enter mon_try_enter
@ -201,10 +160,11 @@ module MonitorMixin
# Enters exclusive section. # Enters exclusive section.
# #
def mon_enter def mon_enter
@mon_mutex.synchronize { if @mon_owner != Thread.current
mon_acquire(@mon_entering_queue) @mon_mutex.lock
@mon_count += 1 @mon_owner = Thread.current
} end
@mon_count += 1
end end
# #
@ -212,13 +172,11 @@ module MonitorMixin
# #
def mon_exit def mon_exit
mon_check_owner mon_check_owner
@mon_mutex.synchronize { @mon_count -=1
@mon_count -= 1 if @mon_count == 0
if @mon_count == 0 @mon_mutex.unlock
mon_release @mon_owner = nil
end end
}
Thread.pass
end end
# #
@ -253,8 +211,6 @@ module MonitorMixin
def mon_initialize def mon_initialize
@mon_owner = nil @mon_owner = nil
@mon_count = 0 @mon_count = 0
@mon_entering_queue = []
@mon_waiting_queue = []
@mon_mutex = Mutex.new @mon_mutex = Mutex.new
end end
@ -264,31 +220,15 @@ module MonitorMixin
end end
end end
def mon_acquire(queue)
while @mon_owner && @mon_owner != Thread.current
queue.push(Thread.current)
@mutex.unlock_and_stop
@mutex.lock
end
@mon_owner = Thread.current
end
def mon_release
@mon_owner = nil
t = @mon_waiting_queue.shift
t = @mon_entering_queue.shift unless t
t.wakeup if t
end
def mon_enter_for_cond(count) def mon_enter_for_cond(count)
mon_acquire(@mon_waiting_queue) @mon_owner = Thread.current
@mon_count = count @mon_count = count
end end
def mon_exit_for_cond def mon_exit_for_cond
count = @mon_count count = @mon_count
@mon_owner = nil
@mon_count = 0 @mon_count = 0
mon_release
return count return count
end end
end end