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:
parent
61d521117a
commit
33a9e63ad9
2 changed files with 36 additions and 92 deletions
|
@ -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
|
||||||
|
|
124
lib/monitor.rb
124
lib/monitor.rb
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue