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