source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/thwait.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 4.3 KB
Line 
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
39require "thread.rb"
40require "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#
54class 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
158end
159
160ThWait = 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.
Note: See TracBrowser for help on using the repository browser.