e3eee29ba3f03516bc6feda4b6227e3276686319
[shibboleth/cpp-xmltooling.git] / xmltooling / util / Threads.h
1 /*
2  *  Copyright 2001-2009 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 xmltooling/util/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 #include <signal.h>
30
31 namespace xmltooling
32 {
33     DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);
34
35     /**
36      * A class for manual thread creation and synchronization.
37      */
38     class XMLTOOL_API Thread
39     {
40         MAKE_NONCOPYABLE(Thread);
41     public:
42         Thread() {}
43         virtual ~Thread() {}
44
45         /**
46          * Disassociate from the thread.
47          *
48          * @return 0 for success, non-zero for failure
49          */
50         virtual int detach()=0;
51
52         /**
53          * Join with the thread and wait for its completion.
54          *
55          * @param thread_return holds the return value of the thread routine
56          * @return 0 for success, non-zero for failure
57          */
58         virtual int join(void** thread_return)=0;
59
60         /**
61          * Kill the thread.
62          *
63          * @param signo the signal to send to the thread
64          * @return 0 for success, non-zero for failure
65          */
66         virtual int kill(int signo)=0;
67
68         /**
69          * Creates a new thread object to run the supplied start routine.
70          *
71          * @param start_routine the function to execute on the thread
72          * @param arg           a parameter for the start routine
73          * @return  the created and running thread object
74          */
75         static Thread* create(void* (*start_routine)(void*), void* arg);
76
77         /**
78          * Exits a thread gracefully.
79          *
80          * @param return_val    the return value for the thread
81          */
82         static void exit(void* return_val);
83
84         /**
85          * Sleeps the current thread for the specified amount of time.
86          *
87          * @param seconds   time to sleep
88          */
89         static void sleep(int seconds);
90 #ifndef WIN32
91         /**
92          * Masks all signals from a thread.
93          */
94         static void mask_all_signals(void);
95
96         /**
97          * Masks specific signals from a thread.
98          *
99          * @param how
100          * @param newmask   the new signal mask
101          * @param oldmask   the old signal mask
102          * @return 0 for success, non-zero for failure
103          */
104         static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);
105 #endif
106     };
107
108     /**
109      * A class for managing Thread Local Storage values.
110      */
111     class XMLTOOL_API ThreadKey
112     {
113         MAKE_NONCOPYABLE(ThreadKey);
114     public:
115         ThreadKey() {}
116         virtual ~ThreadKey() {}
117
118         /**
119          * Sets the value for a TLS key.
120          *
121          * @param data  the value to set
122          * @return 0 for success, non-zero for failure
123          */
124         virtual int setData(void* data)=0;
125
126         /**
127          * Returns the value for a TLS key.
128          *
129          * @return the value or NULL
130          */
131         virtual void* getData() const=0;
132
133         /**
134          * Creates a new TLS key.
135          *
136          * @param destroy_fn    a functon to cleanup key values
137          * @return the new key
138          */
139         static ThreadKey* create(void (*destroy_fn)(void*));
140
141 #ifdef WIN32
142         /**
143          * Allows system to notify TLS implementation when a thread completes.
144          *
145          * <p>Windows doesn't support TLS destructors, so only the DllMain detach
146          * notification can be used to trigger per-thread cleanup.
147          */
148         static void onDetach();
149 #endif
150     };
151
152     /**
153      * A class for managing exclusive access to resources.
154      */
155     class XMLTOOL_API Mutex
156     {
157         MAKE_NONCOPYABLE(Mutex);
158     public:
159         Mutex() {}
160         virtual ~Mutex() {}
161
162         /**
163          * Locks the mutex for exclusive access.
164          *
165          * @return 0 for success, non-zero for failure
166          */
167         virtual int lock()=0;
168
169         /**
170          * Unlocks the mutex for exclusive access.
171          *
172          * @return 0 for success, non-zero for failure
173          */
174         virtual int unlock()=0;
175
176         /**
177          * Creates a new mutex object.
178          *
179          * @return the new mutex
180          */
181         static Mutex* create();
182     };
183
184     /**
185      * A class for managing shared and exclusive access to resources.
186      */
187     class XMLTOOL_API RWLock
188     {
189         MAKE_NONCOPYABLE(RWLock);
190     public:
191         RWLock() {}
192         virtual ~RWLock() {}
193
194         /**
195          * Obtains a shared lock.
196          *
197          * @return 0 for success, non-zero for failure
198          */
199         virtual int rdlock()=0;
200
201         /**
202          * Obtains an exclusive lock.
203          *
204          * @return 0 for success, non-zero for failure
205          */
206         virtual int wrlock()=0;
207
208         /**
209          * Unlocks the lock.
210          *
211          * @return 0 for success, non-zero for failure
212          */
213         virtual int unlock()=0;
214
215         /**
216          * Creates a new read/write lock.
217          *
218          * @return the new lock
219          */
220         static RWLock* create();
221     };
222
223     /**
224      * A class for establishing queues on a mutex based on a periodic condition.
225      */
226     class XMLTOOL_API CondWait
227     {
228         MAKE_NONCOPYABLE(CondWait);
229     public:
230         CondWait() {}
231         virtual ~CondWait() {}
232
233         /**
234          * Waits for a condition variable using the supplied mutex as a queue.
235          *
236          * @param lock  mutex to queue on
237          * @return 0 for success, non-zero for failure
238          */
239         virtual int wait(Mutex* lock)=0;
240
241         /**
242          * Waits for a condition variable using the supplied mutex as a queue,
243          * but only for a certain time limit.
244          *
245          * @param lock          mutex to queue on
246          * @param delay_seconds maximum time to wait before waking up
247          * @return 0 for success, non-zero for failure
248          */
249         virtual int timedwait(Mutex* lock, int delay_seconds)=0;
250
251         /**
252          * Signal a single thread to wake up if a condition changes.
253          *
254          * @return 0 for success, non-zero for failure
255          */
256         virtual int signal()=0;
257
258         /**
259          * Signal all threads to wake up if a condition changes.
260          *
261          * @return 0 for success, non-zero for failure
262          */
263         virtual int broadcast()=0;
264
265         /**
266          * Creates a new condition variable.
267          *
268          * @return the new condition variable
269          */
270         static CondWait* create();
271     };
272
273     /**
274      * RAII wrapper for a mutex lock.
275      */
276     class XMLTOOL_API Lock {
277         MAKE_NONCOPYABLE(Lock);
278     public:
279         /**
280          * Locks and wraps the designated mutex.
281          *
282          * @param mtx mutex to lock
283          */
284         Lock(Mutex* mtx) : mutex(mtx) {
285             mutex->lock();
286         }
287
288         /**
289          * Unlocks the wrapped mutex.
290          */
291         ~Lock() {
292             mutex->unlock();
293         }
294
295     private:
296         Mutex* mutex;
297     };
298
299     /**
300      * RAII wrapper for a shared lock.
301      */
302     class XMLTOOL_API SharedLock {
303         MAKE_NONCOPYABLE(SharedLock);
304     public:
305         /**
306          * Locks and wraps the designated shared lock.
307          *
308          * @param lock      lock to acquire
309          * @param lockit    true if the lock should be acquired here, false if already acquired
310          */
311         SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
312             if (lockit)
313                 rwlock->rdlock();
314         }
315
316         /**
317          * Unlocks the wrapped shared lock.
318          */
319         ~SharedLock() {
320             rwlock->unlock();
321         }
322
323     private:
324         RWLock* rwlock;
325     };
326
327 }
328
329 #endif /* _xmltooling_threads_h */