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 
17 /**
18  * This class is intended to simplify certain common programming techniques.
19  */
20 class ThreadGroup
21 {
22     /**
23      * Creates and starts a new Thread object that executes fn and adds it to
24      * the list of tracked threads.
25      *
26      * Params:
27      *  fn = The thread function.
28      *
29      * Returns:
30      *  A reference to the newly created thread.
31      */
32     final Thread create(void function() fn)
33     {
34         Thread t = new Thread(fn).start();
35 
36         synchronized(this)
37         {
38             m_all[t] = t;
39         }
40         return t;
41     }
42 
43 
44     /**
45      * Creates and starts a new Thread object that executes dg and adds it to
46      * the list of tracked threads.
47      *
48      * Params:
49      *  dg = The thread function.
50      *
51      * Returns:
52      *  A reference to the newly created thread.
53      */
54     final Thread create(void delegate() dg)
55     {
56         Thread t = new Thread(dg).start();
57 
58         synchronized(this)
59         {
60             m_all[t] = t;
61         }
62         return t;
63     }
64 
65 
66     /**
67      * Add t to the list of tracked threads if it is not already being tracked.
68      *
69      * Params:
70      *  t = The thread to add.
71      *
72      * In:
73      *  t must not be null.
74      */
75     final void add(Thread t)
76     in
77     {
78         assert(t);
79     }
80     do
81     {
82         synchronized(this)
83         {
84             m_all[t] = t;
85         }
86     }
87 
88 
89     /**
90      * Removes t from the list of tracked threads.  No operation will be
91      * performed if t is not currently being tracked by this object.
92      *
93      * Params:
94      *  t = The thread to remove.
95      *
96      * In:
97      *  t must not be null.
98      */
99     final void remove(Thread t)
100     in
101     {
102         assert(t);
103     }
104     do
105     {
106         synchronized(this)
107         {
108             m_all.remove(t);
109         }
110     }
111 
112 
113     /**
114      * Operates on all threads currently tracked by this object.
115      */
116     final int opApply(scope int delegate(ref Thread) dg)
117     {
118         synchronized(this)
119         {
120             int ret = 0;
121 
122             // NOTE: This loop relies on the knowledge that m_all uses the
123             //       Thread object for both the key and the mapped value.
124             foreach (Thread t; m_all.keys)
125             {
126                 ret = dg(t);
127                 if (ret)
128                     break;
129             }
130             return ret;
131         }
132     }
133 
134 
135     /**
136      * Iteratively joins all tracked threads.  This function will block add,
137      * remove, and opApply until it completes.
138      *
139      * Params:
140      *  rethrow = Rethrow any unhandled exception which may have caused the
141      *            current thread to terminate.
142      *
143      * Throws:
144      *  Any exception not handled by the joined threads.
145      */
146     final void joinAll(bool rethrow = true)
147     {
148         synchronized(this)
149         {
150             // NOTE: This loop relies on the knowledge that m_all uses the
151             //       Thread object for both the key and the mapped value.
152             foreach (Thread t; m_all.keys)
153             {
154                 t.join(rethrow);
155             }
156         }
157     }
158 
159 
160 private:
161     Thread[Thread]  m_all;
162 }