ruby-changes:20072
From: drbrain <ko1@a...>
Date: Thu, 16 Jun 2011 15:10:13 +0900 (JST)
Subject: [ruby-changes:20072] drbrain:r32119 (trunk): * lib/monitor.rb: Improve documentation. Patch by Sandor Szucs.
drbrain 2011-06-16 15:09:57 +0900 (Thu, 16 Jun 2011) New Revision: 32119 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32119 Log: * lib/monitor.rb: Improve documentation. Patch by Sandor Szucs. [Ruby 1.9 - Bug #4823] Modified files: trunk/ChangeLog trunk/lib/monitor.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 32118) +++ ChangeLog (revision 32119) @@ -1,3 +1,8 @@ +Thu Jun 16 15:09:29 2011 Eric Hodel <drbrain@s...> + + * lib/monitor.rb: Improve documentation. Patch by Sandor Szucs. + [Ruby 1.9 - Bug #4823] + Thu Jun 16 14:54:09 2011 Eric Hodel <drbrain@s...> * lib/webrick/utils.rb: Document WEBrick::Utils. Patch by Olivier Index: lib/monitor.rb =================================================================== --- lib/monitor.rb (revision 32118) +++ lib/monitor.rb (revision 32119) @@ -1,82 +1,92 @@ -=begin +# = monitor.rb +# +# Copyright (C) 2001 Shugo Maeda <shugo@r...> +# +# This library is distributed under the terms of the Ruby license. +# You can freely distribute/modify this library. +# -= monitor.rb - -Copyright (C) 2001 Shugo Maeda <shugo@r...> - -This library is distributed under the terms of the Ruby license. -You can freely distribute/modify this library. - -== example - -This is a simple 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. - -=end - require 'thread' +# +# In concurrent programming, a monitor is an object or module intended to be +# used safely by more than one thread. The defining characteristic of a +# monitor is that its methods are executed with mutual exclusion. That is, at +# each point in time, at most one thread may be executing any of its methods. +# This mutual exclusion greatly simplifies reasoning about the implementation +# of monitors compared to reasoning about parallel code that updates a data +# structure. # -# Adds monitor functionality to an arbitrary object by mixing the module with -# +include+. For example: +# You can read more about the general principles on the Wikipedia page for +# Monitors[http://en.wikipedia.org/wiki/Monitor_%28synchronization%29] +# +# == Examples +# +# === Simple object.extend +# +# 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 <tt>buf.empty?</tt>. The producer thread (main thread) reads a +# line from ARGF and pushes it into buf then calls <tt>empty_cond.signal</tt> +# to notify the consumer thread of new data. +# +# === Simple Class include # -# require 'monitor' +# require 'monitor' +# +# class SynchronizedArray < Array # -# buf = [] -# buf.extend(MonitorMixin) -# empty_cond = buf.new_cond +# include MonitorMixin # -# # consumer -# Thread.start do -# loop do -# buf.synchronize do -# empty_cond.wait_while { buf.empty? } -# print buf.shift -# end -# end -# end +# def initialize(*args) +# super(*args) +# end +# +# alias :old_shift :shift +# alias :old_unshift :unshift +# +# def shift(n=1) +# self.synchronize do +# self.old_shift(n) +# end +# end +# +# def unshift(item) +# self.synchronize do +# self.old_unshift(item) +# end +# end +# +# # other methods ... +# end # -# # producer -# while line = ARGF.gets -# buf.synchronize do -# buf.push(line) -# empty_cond.signal -# end -# end +# +SynchronizedArray+ implements an Array with synchronized access to items. +# This Class is implemented as subclass of Array which includes the +# MonitorMixin module. # -# 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. -# module MonitorMixin # # FIXME: This isn't documented in Nutshell. @@ -215,11 +225,16 @@ private + # Use <tt>extend MonitorMixin</tt> or <tt>include MonitorMixin</tt> instead + # of this constructor. Have look at the examples above to understand how to + # use this module. def initialize(*args) super mon_initialize end + # Initializes the MonitorMixin after being included in a class or when an + # object has been extended with the MonitorMixin def mon_initialize @mon_owner = nil @mon_count = 0 @@ -245,6 +260,16 @@ end end +# Use the Monitor class when you want to have a lock object for blocks with +# mutual exclusion. +# +# require 'monitor' +# +# lock = Monitor.new +# lock.synchronize do +# # exclusive access +# end +# class Monitor include MonitorMixin alias try_enter try_mon_enter @@ -260,8 +285,6 @@ # - All the internals (internal modules Accessible and Initializable, class # ConditionVariable) appear in RDoc. It might be good to hide them, by # making them private, or marking them :nodoc:, etc. -# - The entire example from the RD section at the top is replicated in the RDoc -# comment for MonitorMixin. Does the RD section need to remain? # - RDoc doesn't recognise aliases, so we have mon_synchronize documented, but # not synchronize. # - mon_owner is in Nutshell, but appears as an accessor in a separate module -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/