Update copyright.
[shibboleth/cpp-xmltooling.git] / xmltooling / util / Threads.h
1 /*
2  *  Copyright 2001-2007 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         /**
83          * Sleeps the current thread for the specified amount of time.
84          * 
85          * @param seconds   time to sleep
86          */
87         static void sleep(int seconds);        
88 #ifndef WIN32
89         /**
90          * Masks all signals from a thread. 
91          */
92         static void mask_all_signals(void);
93         
94         /**
95          * Masks specific signals from a thread.
96          * 
97          * @param how
98          * @param newmask   the new signal mask
99          * @param oldmask   the old signal mask
100          * @return 0 for success, non-zero for failure
101          */
102         static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);
103 #endif
104     };
105
106     /**
107      * A class for managing Thread Local Storage values.
108      */
109     class XMLTOOL_API ThreadKey
110     {
111         MAKE_NONCOPYABLE(ThreadKey);
112     public:
113         ThreadKey() {}
114         virtual ~ThreadKey() {}
115
116         /**
117          * Sets the value for a TLS key.
118          * 
119          * @param data  the value to set
120          * @return 0 for success, non-zero for failure
121          */
122         virtual int setData(void* data)=0;
123
124         /**
125          * Returns the value for a TLS key.
126          * 
127          * @return the value or NULL
128          */        
129         virtual void* getData() const=0;
130
131         /**
132          * Creates a new TLS key.
133          * 
134          * @param destroy_fn    a functon to cleanup key values
135          * @return the new key
136          */
137         static ThreadKey* create(void (*destroy_fn)(void*));
138     };
139
140     /**
141      * A class for managing exclusive access to resources.
142      */
143     class XMLTOOL_API Mutex
144     {
145         MAKE_NONCOPYABLE(Mutex);
146     public:
147         Mutex() {}
148         virtual ~Mutex() {}
149
150         /**
151          * Locks the mutex for exclusive access.
152          * 
153          * @return 0 for success, non-zero for failure
154          */
155         virtual int lock()=0;
156         
157         /**
158          * Unlocks the mutex for exclusive access.
159          * 
160          * @return 0 for success, non-zero for failure
161          */
162         virtual int unlock()=0;
163
164         /**
165          * Creates a new mutex object.
166          * 
167          * @return the new mutex
168          */
169         static Mutex* create();
170     };
171     
172     /**
173      * A class for managing shared and exclusive access to resources.
174      */
175     class XMLTOOL_API RWLock
176     {
177         MAKE_NONCOPYABLE(RWLock);
178     public:
179         RWLock() {}
180         virtual ~RWLock() {}
181
182         /**
183          * Obtains a shared lock.
184          * 
185          * @return 0 for success, non-zero for failure
186          */
187         virtual int rdlock()=0;
188         
189         /**
190          * Obtains an exclusive lock.
191          * 
192          * @return 0 for success, non-zero for failure
193          */
194         virtual int wrlock()=0;
195
196         /**
197          * Unlocks the lock.
198          * 
199          * @return 0 for success, non-zero for failure
200          */
201         virtual int unlock()=0;
202
203         /**
204          * Creates a new read/write lock.
205          * 
206          * @return the new lock
207          */
208         static RWLock* create();
209     };
210     
211     /**
212      * A class for establishing queues on a mutex based on a periodic condition.
213      */
214     class XMLTOOL_API CondWait
215     {
216         MAKE_NONCOPYABLE(CondWait);
217     public:
218         CondWait() {}
219         virtual ~CondWait() {}
220         
221         /**
222          * Waits for a condition variable using the supplied mutex as a queue.
223          * 
224          * @param lock  mutex to queue on
225          * @return 0 for success, non-zero for failure
226          */
227         virtual int wait(Mutex* lock)=0;
228         
229         /**
230          * Waits for a condition variable using the supplied mutex as a queue,
231          * but only for a certain time limit.
232          * 
233          * @param lock          mutex to queue on
234          * @param delay_seconds maximum time to wait before waking up
235          * @return 0 for success, non-zero for failure
236          */
237         virtual int timedwait(Mutex* lock, int delay_seconds)=0;
238         
239         /**
240          * Signal a single thread to wake up if a condition changes.
241          * 
242          * @return 0 for success, non-zero for failure
243          */
244         virtual int signal()=0;
245         
246         /**
247          * Signal all threads to wake up if a condition changes.
248          * 
249          * @return 0 for success, non-zero for failure
250          */
251         virtual int broadcast()=0;
252
253         /**
254          * Creates a new condition variable.
255          * 
256          * @return the new condition variable
257          */
258         static CondWait* create();
259     };
260     
261     /**
262      * RAII wrapper for a mutex lock.
263      */
264     class XMLTOOL_API Lock {
265         MAKE_NONCOPYABLE(Lock);
266     public:
267         /**
268          * Locks and wraps the designated mutex.
269          * 
270          * @param mtx mutex to lock 
271          */
272         Lock(Mutex* mtx) : mutex(mtx) {
273             mutex->lock();
274         }
275         
276         /**
277          * Unlocks the wrapped mutex.
278          */
279         ~Lock() {
280             mutex->unlock();
281         }
282     
283     private:
284         Mutex* mutex;
285     };
286     
287     /**
288      * RAII wrapper for a shared lock.
289      */
290     class XMLTOOL_API SharedLock {
291         MAKE_NONCOPYABLE(SharedLock);
292     public:
293         /**
294          * Locks and wraps the designated shared lock.
295          * 
296          * @param lock      lock to acquire 
297          * @param lockit    true if the lock should be acquired here, false if already acquired
298          */
299         SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
300             if (lockit)
301                 rwlock->rdlock();
302         }
303         
304         /**
305          * Unlocks the wrapped shared lock.
306          */
307         ~SharedLock() {
308             rwlock->unlock();
309         }
310     
311     private:
312         RWLock* rwlock;
313     };
314
315 }
316
317 #endif /* _xmltooling_threads_h */