~ubuntu-branches/ubuntu/hardy/ruby1.8/hardy-updates

« back to all changes in this revision

Viewing changes to lib/thwait.rb

  • Committer: Bazaar Package Importer
  • Author(s): akira yamada
  • Date: 2007-03-13 22:11:58 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20070313221158-h3oql37brlaf2go2
Tags: 1.8.6-1
* new upstream version, 1.8.6.
* libruby1.8 conflicts with libopenssl-ruby1.8 (< 1.8.6) (closes: #410018)
* changed packaging style to cdbs from dbs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#
 
2
#   thwait.rb - thread synchronization class
 
3
#       $Release Version: 0.9 $
 
4
#       $Revision: 1.3 $
 
5
#       $Date: 1998/06/26 03:19:34 $
 
6
#       by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)
 
7
#
 
8
# --
 
9
#  feature:
 
10
#  provides synchronization for multiple threads.
 
11
#
 
12
#  class methods:
 
13
#  * ThreadsWait.all_waits(thread1,...)
 
14
#    waits until all of specified threads are terminated.
 
15
#    if a block is supplied for the method, evaluates it for
 
16
#    each thread termination.
 
17
#  * th = ThreadsWait.new(thread1,...)
 
18
#    creates synchronization object, specifying thread(s) to wait.
 
19
#  
 
20
#  methods:
 
21
#  * th.threads
 
22
#    list threads to be synchronized
 
23
#  * th.empty?
 
24
#    is there any thread to be synchronized.
 
25
#  * th.finished?
 
26
#    is there already terminated thread.
 
27
#  * th.join(thread1,...) 
 
28
#    wait for specified thread(s).
 
29
#  * th.join_nowait(threa1,...)
 
30
#    specifies thread(s) to wait.  non-blocking.
 
31
#  * th.next_wait
 
32
#    waits until any of specified threads is terminated.
 
33
#  * th.all_waits
 
34
#    waits until all of specified threads are terminated.
 
35
#    if a block is supplied for the method, evaluates it for
 
36
#    each thread termination.
 
37
#
 
38
 
 
39
require "thread.rb"
 
40
require "e2mmap.rb"
 
41
 
 
42
#
 
43
# This class watches for termination of multiple threads.  Basic functionality
 
44
# (wait until specified threads have terminated) can be accessed through the
 
45
# class method ThreadsWait::all_waits.  Finer control can be gained using
 
46
# instance methods.
 
47
#
 
48
# Example:
 
49
#
 
50
#   ThreadsWait.all_wait(thr1, thr2, ...) do |t|
 
51
#     STDERR.puts "Thread #{t} has terminated."
 
52
#   end
 
53
#
 
54
class ThreadsWait
 
55
  RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'
 
56
  
 
57
  Exception2MessageMapper.extend_to(binding)
 
58
  def_exception("ErrNoWaitingThread", "No threads for waiting.")
 
59
  def_exception("ErrNoFinishedThread", "No finished threads.")
 
60
  
 
61
  #
 
62
  # Waits until all specified threads have terminated.  If a block is provided,
 
63
  # it is executed for each thread termination.
 
64
  #
 
65
  def ThreadsWait.all_waits(*threads) # :yield: thread
 
66
    tw = ThreadsWait.new(*threads)
 
67
    if block_given?
 
68
      tw.all_waits do |th|
 
69
        yield th
 
70
      end
 
71
    else
 
72
      tw.all_waits
 
73
    end
 
74
  end
 
75
  
 
76
  #
 
77
  # Creates a ThreadsWait object, specifying the threads to wait on.
 
78
  # Non-blocking.
 
79
  #
 
80
  def initialize(*threads)
 
81
    @threads = []
 
82
    @wait_queue = Queue.new
 
83
    join_nowait(*threads) unless threads.empty?
 
84
  end
 
85
  
 
86
  # Returns the array of threads in the wait queue.
 
87
  attr :threads
 
88
  
 
89
  #
 
90
  # Returns +true+ if there are no threads to be synchronized.
 
91
  #
 
92
  def empty?
 
93
    @threads.empty?
 
94
  end
 
95
  
 
96
  #
 
97
  # Returns +true+ if any thread has terminated.
 
98
  #
 
99
  def finished?
 
100
    !@wait_queue.empty?
 
101
  end
 
102
  
 
103
  #
 
104
  # Waits for specified threads to terminate.
 
105
  #
 
106
  def join(*threads)
 
107
    join_nowait(*threads)
 
108
    next_wait
 
109
  end
 
110
  
 
111
  #
 
112
  # Specifies the threads that this object will wait for, but does not actually
 
113
  # wait.
 
114
  #
 
115
  def join_nowait(*threads)
 
116
    threads.flatten!
 
117
    @threads.concat threads
 
118
    for th in threads
 
119
      Thread.start(th) do |t|
 
120
        begin
 
121
          t.join
 
122
        ensure
 
123
          @wait_queue.push t
 
124
        end
 
125
      end
 
126
    end
 
127
  end
 
128
  
 
129
  #
 
130
  # Waits until any of the specified threads has terminated, and returns the one
 
131
  # that does.
 
132
  #
 
133
  # If there is no thread to wait, raises +ErrNoWaitingThread+.  If +nonblock+
 
134
  # is true, and there is no terminated thread, raises +ErrNoFinishedThread+.
 
135
  #
 
136
  def next_wait(nonblock = nil)
 
137
    ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
 
138
    begin
 
139
      @threads.delete(th = @wait_queue.pop(nonblock))
 
140
      th
 
141
    rescue ThreadError
 
142
      ThreadsWait.fail ErrNoFinishedThread
 
143
    end
 
144
  end
 
145
  
 
146
  #
 
147
  # Waits until all of the specified threads are terminated.  If a block is
 
148
  # supplied for the method, it is executed for each thread termination.
 
149
  #
 
150
  # Raises exceptions in the same manner as +next_wait+.
 
151
  #
 
152
  def all_waits
 
153
    until @threads.empty?
 
154
      th = next_wait
 
155
      yield th if block_given?
 
156
    end
 
157
  end
 
158
end
 
159
 
 
160
ThWait = ThreadsWait
 
161
 
 
162
 
 
163
# Documentation comments:
 
164
#  - Source of documentation is evenly split between Nutshell, existing
 
165
#    comments, and my own rephrasing.
 
166
#  - I'm not particularly confident that the comments are all exactly correct.
 
167
#  - The history, etc., up the top appears in the RDoc output.  Perhaps it would
 
168
#    be better to direct that not to appear, and put something else there
 
169
#    instead.