| Module | MonitorMixin |
| In: |
monitor.rb
|
Adds monitor functionality to an arbitrary object by mixing the module with include. For example:
require 'monitor.rb'
buf = []
buf.extend(MonitorMixin)
empty_cond = buf.new_cond
# consumer
Thread.start do
loop do
buf.synchronize do
empty_cond.wait_while { buf.empty? }
print buf.shift
end
end
end
# producer
while line = ARGF.gets
buf.synchronize do
buf.push(line)
empty_cond.signal
end
end
The consumer thread waits for the producer thread to push a line to buf while buf.empty?, and the producer thread (main thread) reads a line from ARGF and push it to buf, then call empty_cond.signal.
Public Class methods
# File monitor.rb, line 173
173: def self.extend_object(obj)
174: super(obj)
175: obj.instance_eval {mon_initialize()}
176: end
Public Instance methods
Enters exclusive section.
# File monitor.rb, line 200
200: def mon_enter
201: Thread.critical = true
202: mon_acquire(@mon_entering_queue)
203: @mon_count += 1
204: Thread.critical = false
205: end
Leaves exclusive section.
# File monitor.rb, line 210
210: def mon_exit
211: mon_check_owner
212: Thread.critical = true
213: @mon_count -= 1
214: if @mon_count == 0
215: mon_release
216: end
217: Thread.critical = false
218: Thread.pass
219: end
Enters exclusive section and executes the block. Leaves the exclusive section automatically when the block exits. See example under MonitorMixin.
# File monitor.rb, line 226
226: def mon_synchronize
227: mon_enter
228: begin
229: yield
230: ensure
231: mon_exit
232: end
233: end
Attempts to enter exclusive section. Returns false if lock fails.
# File monitor.rb, line 181
181: def mon_try_enter
182: result = false
183: Thread.critical = true
184: if @mon_owner.nil?
185: @mon_owner = Thread.current
186: end
187: if @mon_owner == Thread.current
188: @mon_count += 1
189: result = true
190: end
191: Thread.critical = false
192: return result
193: end