module MonitorMixin
See MRI Ruby’s MonitorMixin
This file is derived from MRI Ruby 1.9.3 monitor.rb
Copyright © 2001 Shugo Maeda <shugo@ruby-lang.org>
The only changes are constant lookups, it dynamically uses thread constants from the included class/extended object
Note this relaces monitor.rb defined by ruby - so even if you don’t include empathy you may end up using this module.
Public Class Methods
@private
# File lib/monitor.rb, line 76 def self.extend_object(obj) super(obj) obj.__send__(:mon_initialize) end
Use extend MonitorMixin
or include MonitorMixin
instead of this constructor. Have look at the examples above to understand how to use this module.
# File lib/monitor.rb, line 149 def initialize(*args) super mon_initialize end
Public Instance Methods
Enters exclusive section.
@return [void]
# File lib/monitor.rb, line 102 def mon_enter if @mon_owner != mon_class_lookup(:Thread).current @mon_mutex.lock @mon_owner = mon_class_lookup(:Thread).current end @mon_count += 1 end
Leaves exclusive section.
@return [void]
# File lib/monitor.rb, line 114 def mon_exit mon_check_owner @mon_count -=1 if @mon_count == 0 @mon_owner = nil @mon_mutex.unlock end end
Enters exclusive section and executes the block. Leaves the exclusive section automatically when the block exits. @return [void]
# File lib/monitor.rb, line 127 def mon_synchronize mon_enter begin yield ensure mon_exit end end
Attempts to enter exclusive section.
@return [Boolean] whether entry was successful
# File lib/monitor.rb, line 85 def mon_try_enter if @mon_owner != mon_class_lookup(:Thread).current unless @mon_mutex.try_lock return false end @mon_owner = mon_class_lookup(:Thread).current end @mon_count += 1 return true end
@return [ConditionVariable] a new condition variable associated with the receiver.
# File lib/monitor.rb, line 140 def new_cond return ConditionVariable.new(self) end
Private Instance Methods
# File lib/monitor.rb, line 168 def mon_check_owner if @mon_owner != mon_class_lookup(:Thread).current raise mon_class_lookup(:ThreadError), "current thread not owner" end end
looks up namespace hierarchy for an empathised module
# File lib/monitor.rb, line 187 def mon_class_lookup(const) @mon_empathised_module.const_get(const,false) end
# File lib/monitor.rb, line 174 def mon_enter_for_cond(count) @mon_owner = mon_class_lookup(:Thread).current @mon_count = count end
# File lib/monitor.rb, line 179 def mon_exit_for_cond count = @mon_count @mon_owner = nil @mon_count = 0 return count end
Initializes the MonitorMixin
after being included in a class or when an object has been extended with the MonitorMixin
# File lib/monitor.rb, line 156 def mon_initialize @mon_owner = nil @mon_count = 0 # Find the appropriate empathised module to use when resolving references to Thread, Mutex etc.. parts = self.class.name.split("::")[0..-2] parents = parts.inject([Object]) { |result,name| result.unshift(result.first.const_get(name,false)) } @mon_empathised_module = parents.detect { |p| p.instance_variable_get(:@empathised) } || Object @mon_mutex = mon_class_lookup(:Mutex).new end