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