The OpenD Programming Language

1 /**
2  * The osthread module provides types used in threads modules.
3  *
4  * Copyright: Copyright Sean Kelly 2005 - 2012.
5  * License: Distributed under the
6  *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
7  *    (See accompanying file LICENSE)
8  * Authors:   Sean Kelly, Walter Bright, Alex Rønne Petersen, Martin Nowak
9  * Source:    $(DRUNTIMESRC core/thread/osthread.d)
10  */
11 
12 module core.thread.threadgroup;
13 
14 import core.thread.osthread;
15 
16 version(WebAssembly) {} else:
17 
18 
19 /**
20  * This class is intended to simplify certain common programming techniques.
21  */
22 class ThreadGroup
23 {
24     /**
25      * Creates and starts a new Thread object that executes fn and adds it to
26      * the list of tracked threads.
27      *
28      * Params:
29      *  fn = The thread function.
30      *
31      * Returns:
32      *  A reference to the newly created thread.
33      */
34     final Thread create(void function() fn)
35     {
36         Thread t = new Thread(fn).start();
37 
38         synchronized(this)
39         {
40             m_all[t] = t;
41         }
42         return t;
43     }
44 
45 
46     /**
47      * Creates and starts a new Thread object that executes dg and adds it to
48      * the list of tracked threads.
49      *
50      * Params:
51      *  dg = The thread function.
52      *
53      * Returns:
54      *  A reference to the newly created thread.
55      */
56     final Thread create(void delegate() dg)
57     {
58         Thread t = new Thread(dg).start();
59 
60         synchronized(this)
61         {
62             m_all[t] = t;
63         }
64         return t;
65     }
66 
67 
68     /**
69      * Add t to the list of tracked threads if it is not already being tracked.
70      *
71      * Params:
72      *  t = The thread to add.
73      *
74      * In:
75      *  t must not be null.
76      */
77     final void add(Thread t)
78     in
79     {
80         assert(t);
81     }
82     do
83     {
84         synchronized(this)
85         {
86             m_all[t] = t;
87         }
88     }
89 
90 
91     /**
92      * Removes t from the list of tracked threads.  No operation will be
93      * performed if t is not currently being tracked by this object.
94      *
95      * Params:
96      *  t = The thread to remove.
97      *
98      * In:
99      *  t must not be null.
100      */
101     final void remove(Thread t)
102     in
103     {
104         assert(t);
105     }
106     do
107     {
108         synchronized(this)
109         {
110             m_all.remove(t);
111         }
112     }
113 
114 
115     /**
116      * Operates on all threads currently tracked by this object.
117      */
118     final int opApply(scope int delegate(ref Thread) dg)
119     {
120         synchronized(this)
121         {
122             int ret = 0;
123 
124             // NOTE: This loop relies on the knowledge that m_all uses the
125             //       Thread object for both the key and the mapped value.
126             foreach (Thread t; m_all.keys)
127             {
128                 ret = dg(t);
129                 if (ret)
130                     break;
131             }
132             return ret;
133         }
134     }
135 
136 
137     /**
138      * Iteratively joins all tracked threads.  This function will block add,
139      * remove, and opApply until it completes.
140      *
141      * Params:
142      *  rethrow = Rethrow any unhandled exception which may have caused the
143      *            current thread to terminate.
144      *
145      * Throws:
146      *  Any exception not handled by the joined threads.
147      */
148     final void joinAll(bool rethrow = true)
149     {
150         synchronized(this)
151         {
152             // NOTE: This loop relies on the knowledge that m_all uses the
153             //       Thread object for both the key and the mapped value.
154             foreach (Thread t; m_all.keys)
155             {
156                 t.join(rethrow);
157             }
158         }
159     }
160 
161 
162 private:
163     Thread[Thread]  m_all;
164 }