Increase parser timeout values, output complete document when saving backup copies.
[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 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>\r
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
142     /**
143      * A class for managing exclusive access to resources.
144      */
145     class XMLTOOL_API Mutex
146     {
147         MAKE_NONCOPYABLE(Mutex);
148     public:
149         Mutex() {}
150         virtual ~Mutex() {}
151
152         /**
153          * Locks the mutex for exclusive access.
154          * 
155          * @return 0 for success, non-zero for failure
156          */
157         virtual int lock()=0;
158         
159         /**
160          * Unlocks the mutex for exclusive access.
161          * 
162          * @return 0 for success, non-zero for failure
163          */
164         virtual int unlock()=0;
165
166         /**
167          * Creates a new mutex object.
168          * 
169          * @return the new mutex
170          */
171         static Mutex* create();
172     };
173     
174     /**
175      * A class for managing shared and exclusive access to resources.
176      */
177     class XMLTOOL_API RWLock
178     {
179         MAKE_NONCOPYABLE(RWLock);
180     public:
181         RWLock() {}
182         virtual ~RWLock() {}
183
184         /**
185          * Obtains a shared lock.
186          * 
187          * @return 0 for success, non-zero for failure
188          */
189         virtual int rdlock()=0;
190         
191         /**
192          * Obtains an exclusive lock.
193          * 
194          * @return 0 for success, non-zero for failure
195          */
196         virtual int wrlock()=0;
197
198         /**
199          * Unlocks the lock.
200          * 
201          * @return 0 for success, non-zero for failure
202          */
203         virtual int unlock()=0;
204
205         /**
206          * Creates a new read/write lock.
207          * 
208          * @return the new lock
209          */
210         static RWLock* create();
211     };
212     
213     /**
214      * A class for establishing queues on a mutex based on a periodic condition.
215      */
216     class XMLTOOL_API CondWait
217     {
218         MAKE_NONCOPYABLE(CondWait);
219     public:
220         CondWait() {}
221         virtual ~CondWait() {}
222         
223         /**
224          * Waits for a condition variable using the supplied mutex as a queue.
225          * 
226          * @param lock  mutex to queue on
227          * @return 0 for success, non-zero for failure
228          */
229         virtual int wait(Mutex* lock)=0;
230         
231         /**
232          * Waits for a condition variable using the supplied mutex as a queue,
233          * but only for a certain time limit.
234          * 
235          * @param lock          mutex to queue on
236          * @param delay_seconds maximum time to wait before waking up
237          * @return 0 for success, non-zero for failure
238          */
239         virtual int timedwait(Mutex* lock, int delay_seconds)=0;
240         
241         /**
242          * Signal a single thread to wake up if a condition changes.
243          * 
244          * @return 0 for success, non-zero for failure
245          */
246         virtual int signal()=0;
247         
248         /**
249          * Signal all threads to wake up if a condition changes.
250          * 
251          * @return 0 for success, non-zero for failure
252          */
253         virtual int broadcast()=0;
254
255         /**
256          * Creates a new condition variable.
257          * 
258          * @return the new condition variable
259          */
260         static CondWait* create();
261     };
262     
263     /**
264      * RAII wrapper for a mutex lock.
265      */
266     class XMLTOOL_API Lock {
267         MAKE_NONCOPYABLE(Lock);
268     public:
269         /**
270          * Locks and wraps the designated mutex.
271          * 
272          * @param mtx mutex to lock 
273          */
274         Lock(Mutex* mtx) : mutex(mtx) {
275             mutex->lock();
276         }
277         
278         /**
279          * Unlocks the wrapped mutex.
280          */
281         ~Lock() {
282             mutex->unlock();
283         }
284     
285     private:
286         Mutex* mutex;
287     };
288     
289     /**
290      * RAII wrapper for a shared lock.
291      */
292     class XMLTOOL_API SharedLock {
293         MAKE_NONCOPYABLE(SharedLock);
294     public:
295         /**
296          * Locks and wraps the designated shared lock.
297          * 
298          * @param lock      lock to acquire 
299          * @param lockit    true if the lock should be acquired here, false if already acquired
300          */
301         SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
302             if (lockit)
303                 rwlock->rdlock();
304         }
305         
306         /**
307          * Unlocks the wrapped shared lock.
308          */
309         ~SharedLock() {
310             rwlock->unlock();
311         }
312     
313     private:
314         RWLock* rwlock;
315     };
316
317 }
318
319 #endif /* _xmltooling_threads_h */