Threading support.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / Threads.h
1 /*\r
2  *  Copyright 2001-2006 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * @file Threads.h\r
19  * \r
20  * Thread and locking wrappers \r
21  */\r
22 \r
23 #ifndef _xmltooling_threads_h\r
24 #define _xmltooling_threads_h\r
25 \r
26 #include <xmltooling/base.h>\r
27 #include <xmltooling/exceptions.h>\r
28 \r
29 namespace xmltooling\r
30 {\r
31     DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);\r
32     \r
33     /**\r
34      * A class for manual thread creation and synchronization.\r
35      */\r
36     class XMLTOOL_API Thread\r
37     {\r
38         MAKE_NONCOPYABLE(Thread);\r
39     public:\r
40         Thread() {}\r
41         virtual ~Thread() {}\r
42 \r
43         /**\r
44          * Disassociate from the thread.\r
45          * \r
46          * @return 0 for success, non-zero for failure\r
47          */\r
48         virtual int detach()=0;\r
49         \r
50         /**\r
51          * Join with the thread and wait for its completion.\r
52          * \r
53          * @param thread_return holds the return value of the thread routine\r
54          * @return 0 for success, non-zero for failure\r
55          */\r
56         virtual int join(void** thread_return)=0;\r
57         \r
58         /**\r
59          * Kill the thread.\r
60          * \r
61          * @param signo the signal to send to the thread\r
62          * @return 0 for success, non-zero for failure\r
63          */\r
64         virtual int kill(int signo)=0;\r
65         \r
66         /**\r
67          * Creates a new thread object to run the supplied start routine.\r
68          * \r
69          * @param start_routine the function to execute on the thread\r
70          * @param arg           a parameter for the start routine\r
71          * @return  the created and running thread object \r
72          */\r
73         static Thread* create(void* (*start_routine)(void*), void* arg);\r
74         \r
75         /**\r
76          * Exits a thread gracefully.\r
77          * \r
78          * @param return_val    the return value for the thread\r
79          */\r
80         static void exit(void* return_val);\r
81         \r
82 #ifndef WIN32\r
83         /**\r
84          * Masks all signals from a thread. \r
85          */\r
86         static void mask_all_signals(void);\r
87         \r
88         /**\r
89          * Masks specific signals from a thread.\r
90          * \r
91          * @param how\r
92          * @param newmask   the new signal mask\r
93          * @param oldmask   the old signal mask\r
94          * @return 0 for success, non-zero for failure\r
95          */\r
96         static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);\r
97 #endif\r
98     };\r
99 \r
100     /**\r
101      * A class for managing Thread Local Storage values.\r
102      */\r
103     class XMLTOOL_API ThreadKey\r
104     {\r
105         MAKE_NONCOPYABLE(ThreadKey);\r
106     public:\r
107         ThreadKey() {}\r
108         virtual ~ThreadKey() {}\r
109 \r
110         /**\r
111          * Sets the value for a TLS key.\r
112          * \r
113          * @param data  the value to set\r
114          * @return 0 for success, non-zero for failure\r
115          */\r
116         virtual int setData(void* data)=0;\r
117 \r
118         /**\r
119          * Returns the value for a TLS key.\r
120          * \r
121          * @return the value or NULL\r
122          */        \r
123         virtual void* getData() const=0;\r
124 \r
125         /**\r
126          * Creates a new TLS key.\r
127          * \r
128          * @param destroy_fn    a functon to cleanup key values\r
129          * @return the new key\r
130          */\r
131         static ThreadKey* create(void (*destroy_fn)(void*));\r
132     };\r
133 \r
134     /**\r
135      * A class for managing exclusive access to resources.\r
136      */\r
137     class XMLTOOL_API Mutex\r
138     {\r
139         MAKE_NONCOPYABLE(Mutex);\r
140     public:\r
141         Mutex() {}\r
142         virtual ~Mutex() {}\r
143 \r
144         /**\r
145          * Locks the mutex for exclusive access.\r
146          * \r
147          * @return 0 for success, non-zero for failure\r
148          */\r
149         virtual int lock()=0;\r
150         \r
151         /**\r
152          * Unlocks the mutex for exclusive access.\r
153          * \r
154          * @return 0 for success, non-zero for failure\r
155          */\r
156         virtual int unlock()=0;\r
157 \r
158         /**\r
159          * Creates a new mutex object.\r
160          * \r
161          * @return the new mutex\r
162          */\r
163         static Mutex* create();\r
164     };\r
165     \r
166     /**\r
167      * A class for managing shared and exclusive access to resources.\r
168      */\r
169     class XMLTOOL_API RWLock\r
170     {\r
171         MAKE_NONCOPYABLE(RWLock);\r
172     public:\r
173         RWLock() {}\r
174         virtual ~RWLock() {}\r
175 \r
176         /**\r
177          * Obtains a shared lock.\r
178          * \r
179          * @return 0 for success, non-zero for failure\r
180          */\r
181         virtual int rdlock()=0;\r
182         \r
183         /**\r
184          * Obtains an exclusive lock.\r
185          * \r
186          * @return 0 for success, non-zero for failure\r
187          */\r
188         virtual int wrlock()=0;\r
189 \r
190         /**\r
191          * Unlocks the lock.\r
192          * \r
193          * @return 0 for success, non-zero for failure\r
194          */\r
195         virtual int unlock()=0;\r
196 \r
197         /**\r
198          * Creates a new read/write lock.\r
199          * \r
200          * @return the new lock\r
201          */\r
202         static RWLock* create();\r
203     };\r
204     \r
205     /**\r
206      * A class for establishing queues on a mutex based on a periodic condition.\r
207      */\r
208     class XMLTOOL_API CondWait\r
209     {\r
210         MAKE_NONCOPYABLE(CondWait);\r
211     public:\r
212         CondWait() {}\r
213         virtual ~CondWait() {}\r
214         \r
215         /**\r
216          * Waits for a condition variable using the supplied mutex as a queue.\r
217          * \r
218          * @param lock  mutex to queue on\r
219          * @return 0 for success, non-zero for failure\r
220          */\r
221         virtual int wait(Mutex* lock)=0;\r
222         \r
223         /**\r
224          * Waits for a condition variable using the supplied mutex as a queue,\r
225          * but only for a certain time limit.\r
226          * \r
227          * @param lock          mutex to queue on\r
228          * @param delay_seconds maximum time to wait before waking up\r
229          * @return 0 for success, non-zero for failure\r
230          */\r
231         virtual int timedwait(Mutex* lock, int delay_seconds)=0;\r
232         \r
233         /**\r
234          * Signal a single thread to wake up if a condition changes.\r
235          * \r
236          * @return 0 for success, non-zero for failure\r
237          */\r
238         virtual int signal()=0;\r
239         \r
240         /**\r
241          * Signal all threads to wake up if a condition changes.\r
242          * \r
243          * @return 0 for success, non-zero for failure\r
244          */\r
245         virtual int broadcast()=0;\r
246 \r
247         /**\r
248          * Creates a new condition variable.\r
249          * \r
250          * @return the new condition variable\r
251          */\r
252         static CondWait* create();\r
253     };\r
254     \r
255     /**\r
256      * RAII wrapper for a mutex lock.\r
257      */\r
258     class XMLTOOL_API Lock {\r
259         MAKE_NONCOPYABLE(Lock);\r
260     public:\r
261         /**\r
262          * Locks and wraps the designated mutex.\r
263          * \r
264          * @param mtx mutex to lock \r
265          */\r
266         Lock(Mutex* mtx) : mutex(mtx) {\r
267             mutex->lock();\r
268         }\r
269         \r
270         /**\r
271          * Unlocks the wrapped mutex.\r
272          */\r
273         ~Lock() {\r
274             mutex->unlock();\r
275         }\r
276     \r
277     private:\r
278         Mutex* mutex;\r
279     };\r
280     \r
281     /**\r
282      * RAII wrapper for a shared lock.\r
283      */\r
284     class XMLTOOL_API ReadLock {\r
285         MAKE_NONCOPYABLE(ReadLock);\r
286     public:\r
287         /**\r
288          * Locks and wraps the designated shared lock.\r
289          * \r
290          * @param lock lock to acquire \r
291          */\r
292         ReadLock(RWLock* lock) : rwlock(lock) {\r
293             rwlock->rdlock();\r
294         }\r
295         \r
296         /**\r
297          * Unlocks the wrapped shared lock.\r
298          */\r
299         ~ReadLock() {\r
300             rwlock->unlock();\r
301         }\r
302     \r
303     private:\r
304         RWLock* rwlock;\r
305     };\r
306 \r
307 }\r
308 \r
309 #endif /* _xmltooling_threads_h */\r