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>
36 DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);
39 * A class for manual thread creation and synchronization.
41 class XMLTOOL_API Thread
43 MAKE_NONCOPYABLE(Thread);
50 * Disassociate from the thread.
52 * @return 0 for success, non-zero for failure
54 virtual int detach()=0;
57 * Join with the thread and wait for its completion.
59 * @param thread_return holds the return value of the thread routine
60 * @return 0 for success, non-zero for failure
62 virtual int join(void** thread_return)=0;
67 * @param signo the signal to send to the thread
68 * @return 0 for success, non-zero for failure
70 virtual int kill(int signo)=0;
73 * Creates a new thread object to run the supplied start routine.
75 * @param start_routine the function to execute on the thread
76 * @param arg a parameter for the start routine
77 * @param stacksize size of stack to use, or 0 for default
78 * @return the created and running thread object
80 static Thread* create(void* (*start_routine)(void*), void* arg, size_t stacksize=0);
83 * Exits a thread gracefully.
85 * @param return_val the return value for the thread
87 static void exit(void* return_val);
90 * Sleeps the current thread for the specified amount of time.
92 * @param seconds time to sleep
94 static void sleep(int seconds);
97 * Masks all signals from a thread.
99 static void mask_all_signals(void);
102 * Masks specific signals from a thread.
105 * @param newmask the new signal mask
106 * @param oldmask the old signal mask
107 * @return 0 for success, non-zero for failure
109 static int mask_signals(int how, const sigset_t *newmask, sigset_t *oldmask);
114 * A class for managing Thread Local Storage values.
116 class XMLTOOL_API ThreadKey
118 MAKE_NONCOPYABLE(ThreadKey);
122 virtual ~ThreadKey() {}
125 * Sets the value for a TLS key.
127 * @param data the value to set
128 * @return 0 for success, non-zero for failure
130 virtual int setData(void* data)=0;
133 * Returns the value for a TLS key.
135 * @return the value or nullptr
137 virtual void* getData() const=0;
140 * Creates a new TLS key.
142 * @param destroy_fn a functon to cleanup key values
143 * @return the new key
145 static ThreadKey* create(void (*destroy_fn)(void*));
149 * Allows system to notify TLS implementation when a thread completes.
151 * <p>Windows doesn't support TLS destructors, so only the DllMain detach
152 * notification can be used to trigger per-thread cleanup.
154 static void onDetach();
159 * A class for managing exclusive access to resources.
161 class XMLTOOL_API Mutex
163 MAKE_NONCOPYABLE(Mutex);
170 * Locks the mutex for exclusive access.
172 * @return 0 for success, non-zero for failure
174 virtual int lock()=0;
177 * Unlocks the mutex for exclusive access.
179 * @return 0 for success, non-zero for failure
181 virtual int unlock()=0;
184 * Creates a new mutex object.
186 * @return the new mutex
188 static Mutex* create();
192 * A class for managing shared and exclusive access to resources.
194 class XMLTOOL_API RWLock
196 MAKE_NONCOPYABLE(RWLock);
203 * Obtains a shared lock.
205 * @return 0 for success, non-zero for failure
207 virtual int rdlock()=0;
210 * Obtains an exclusive lock.
212 * @return 0 for success, non-zero for failure
214 virtual int wrlock()=0;
219 * @return 0 for success, non-zero for failure
221 virtual int unlock()=0;
224 * Creates a new read/write lock.
226 * @return the new lock
228 static RWLock* create();
232 * A class for establishing queues on a mutex based on a periodic condition.
234 class XMLTOOL_API CondWait
236 MAKE_NONCOPYABLE(CondWait);
240 virtual ~CondWait() {}
243 * Waits for a condition variable using the supplied mutex as a queue.
245 * @param lock mutex to queue on
246 * @return 0 for success, non-zero for failure
248 virtual int wait(Mutex* lock)=0;
251 * Waits for a condition variable using the supplied mutex as a queue,
252 * but only for a certain time limit.
254 * @param lock mutex to queue on
255 * @param delay_seconds maximum time to wait before waking up
256 * @return 0 for success, non-zero for failure
258 virtual int timedwait(Mutex* lock, int delay_seconds)=0;
261 * Signal a single thread to wake up if a condition changes.
263 * @return 0 for success, non-zero for failure
265 virtual int signal()=0;
268 * Signal all threads to wake up if a condition changes.
270 * @return 0 for success, non-zero for failure
272 virtual int broadcast()=0;
275 * Creates a new condition variable.
277 * @return the new condition variable
279 static CondWait* create();
283 * RAII wrapper for a mutex lock.
285 class XMLTOOL_API Lock {
286 MAKE_NONCOPYABLE(Lock);
289 * Locks and wraps the designated mutex.
291 * @param mtx mutex to lock
293 Lock(Mutex* mtx) : mutex(mtx) {
299 * Locks and wraps the designated mutex.
301 * @param mtx mutex to lock
303 Lock(Mutex& mtx) : mutex(&mtx) {
308 * Unlocks the wrapped mutex.
320 * RAII wrapper for a shared lock.
322 class XMLTOOL_API SharedLock {
323 MAKE_NONCOPYABLE(SharedLock);
326 * Locks and wraps the designated shared lock.
328 * @param lock lock to acquire
329 * @param lockit true if the lock should be acquired here, false if already acquired
331 SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
332 if (rwlock && lockit)
337 * Unlocks the wrapped shared lock.
350 #endif /* _xmltooling_threads_h */