2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
22 * @file xmltooling/util/Threads.h
24 * Thread and locking wrappers.
27 #ifndef _xmltooling_threads_h
28 #define _xmltooling_threads_h
30 #include <xmltooling/exceptions.h>
33 #include <boost/scoped_ptr.hpp>
38 DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);
41 * A class for manual thread creation and synchronization.
43 class XMLTOOL_API Thread
45 MAKE_NONCOPYABLE(Thread);
52 * Disassociate from the thread.
54 * @return 0 for success, non-zero for failure
56 virtual int detach()=0;
59 * Join with the thread and wait for its completion.
61 * @param thread_return holds the return value of the thread routine
62 * @return 0 for success, non-zero for failure
64 virtual int join(void** thread_return)=0;
69 * @param signo the signal to send to the thread
70 * @return 0 for success, non-zero for failure
72 virtual int kill(int signo)=0;
75 * Creates a new thread object to run the supplied start routine.
77 * @param start_routine the function to execute on the thread
78 * @param arg a parameter for the start routine
79 * @param stacksize size of stack to use, or 0 for default
80 * @return the created and running thread object
82 static Thread* create(void* (*start_routine)(void*), void* arg, size_t stacksize=0);
85 * Exits a thread gracefully.
87 * @param return_val the return value for the thread
89 static void exit(void* return_val);
92 * Sleeps the current thread for the specified amount of time.
94 * @param seconds time to sleep
96 static void sleep(int seconds);
99 * Masks all signals from a thread.
101 static void mask_all_signals(void);
104 * Masks specific signals from a thread.
107 * @param newmask the new signal mask
108 * @param oldmask the old signal mask
109 * @return 0 for success, non-zero for failure
111 static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);
116 * A class for managing Thread Local Storage values.
118 class XMLTOOL_API ThreadKey
120 MAKE_NONCOPYABLE(ThreadKey);
124 virtual ~ThreadKey() {}
127 * Sets the value for a TLS key.
129 * @param data the value to set
130 * @return 0 for success, non-zero for failure
132 virtual int setData(void* data)=0;
135 * Returns the value for a TLS key.
137 * @return the value or nullptr
139 virtual void* getData() const=0;
142 * Creates a new TLS key.
144 * @param destroy_fn a functon to cleanup key values
145 * @return the new key
147 static ThreadKey* create(void (*destroy_fn)(void*));
151 * Allows system to notify TLS implementation when a thread completes.
153 * <p>Windows doesn't support TLS destructors, so only the DllMain detach
154 * notification can be used to trigger per-thread cleanup.
156 static void onDetach();
161 * A class for managing exclusive access to resources.
163 class XMLTOOL_API Mutex
165 MAKE_NONCOPYABLE(Mutex);
172 * Locks the mutex for exclusive access.
174 * @return 0 for success, non-zero for failure
176 virtual int lock()=0;
179 * Unlocks the mutex for exclusive access.
181 * @return 0 for success, non-zero for failure
183 virtual int unlock()=0;
186 * Creates a new mutex object.
188 * @return the new mutex
190 static Mutex* create();
194 * A class for managing shared and exclusive access to resources.
196 class XMLTOOL_API RWLock
198 MAKE_NONCOPYABLE(RWLock);
205 * Obtains a shared lock.
207 * @return 0 for success, non-zero for failure
209 virtual int rdlock()=0;
212 * Obtains an exclusive lock.
214 * @return 0 for success, non-zero for failure
216 virtual int wrlock()=0;
221 * @return 0 for success, non-zero for failure
223 virtual int unlock()=0;
226 * Creates a new read/write lock.
228 * @return the new lock
230 static RWLock* create();
234 * A class for establishing queues on a mutex based on a periodic condition.
236 class XMLTOOL_API CondWait
238 MAKE_NONCOPYABLE(CondWait);
242 virtual ~CondWait() {}
245 * Waits for a condition variable using the supplied mutex as a queue.
247 * @param lock mutex to queue on
248 * @return 0 for success, non-zero for failure
250 virtual int wait(Mutex* lock)=0;
253 * Waits for a condition variable using the supplied mutex as a queue,
254 * but only for a certain time limit.
256 * @param lock mutex to queue on
257 * @param delay_seconds maximum time to wait before waking up
258 * @return 0 for success, non-zero for failure
260 virtual int timedwait(Mutex* lock, int delay_seconds)=0;
263 * Signal a single thread to wake up if a condition changes.
265 * @return 0 for success, non-zero for failure
267 virtual int signal()=0;
270 * Signal all threads to wake up if a condition changes.
272 * @return 0 for success, non-zero for failure
274 virtual int broadcast()=0;
277 * Creates a new condition variable.
279 * @return the new condition variable
281 static CondWait* create();
285 * RAII wrapper for a mutex lock.
287 class XMLTOOL_API Lock {
288 MAKE_NONCOPYABLE(Lock);
291 * Locks and wraps the designated mutex.
293 * @param mtx mutex to lock
295 Lock(Mutex* mtx) : mutex(mtx) {
301 * Locks and wraps the designated mutex.
303 * @param mtx mutex to lock
305 Lock(Mutex& mtx) : mutex(&mtx) {
310 * Locks and wraps the designated mutex.
312 * @param mtx mutex to lock
314 Lock(const std::auto_ptr<Mutex>& mtx) : mutex(mtx.get()) {
320 * Locks and wraps the designated mutex.
322 * @param mtx mutex to lock
324 Lock(const boost::scoped_ptr<Mutex>& mtx) : mutex(mtx.get()) {
330 * Unlocks the wrapped mutex, if any.
338 * Releases control of the original Mutex and returns it without unlocking it.
340 * @return the original, locked Mutex
353 * RAII wrapper for a shared lock.
355 class XMLTOOL_API SharedLock {
356 MAKE_NONCOPYABLE(SharedLock);
359 * Locks and wraps the designated shared lock.
361 * @param lock lock to acquire
362 * @param lockit true if the lock should be acquired here, false if already acquired
364 SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
365 if (rwlock && lockit)
370 * Locks and wraps the designated shared lock.
372 * @param lock lock to acquire
373 * @param lockit true if the lock should be acquired here, false if already acquired
375 SharedLock(const std::auto_ptr<RWLock>& lock, bool lockit=true) : rwlock(lock.get()) {
376 if (rwlock && lockit)
381 * Locks and wraps the designated shared lock.
383 * @param lock lock to acquire
384 * @param lockit true if the lock should be acquired here, false if already acquired
386 SharedLock(const boost::scoped_ptr<RWLock>& lock, bool lockit=true) : rwlock(lock.get()) {
387 if (rwlock && lockit)
392 * Unlocks the wrapped shared lock, if any.
400 * Releases control of the original shared lock and returns it without unlocking it.
402 * @return the original shared lock
405 RWLock* ret = rwlock;
416 #endif /* _xmltooling_threads_h */