xref: /freebsd/contrib/unbound/util/locks.h (revision 3005e0a3)
1b7579f77SDag-Erling Smørgrav /**
2b7579f77SDag-Erling Smørgrav  * util/locks.h - unbound locking primitives
3b7579f77SDag-Erling Smørgrav  *
4b7579f77SDag-Erling Smørgrav  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5b7579f77SDag-Erling Smørgrav  *
6b7579f77SDag-Erling Smørgrav  * This software is open source.
7b7579f77SDag-Erling Smørgrav  *
8b7579f77SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
9b7579f77SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
10b7579f77SDag-Erling Smørgrav  * are met:
11b7579f77SDag-Erling Smørgrav  *
12b7579f77SDag-Erling Smørgrav  * Redistributions of source code must retain the above copyright notice,
13b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer.
14b7579f77SDag-Erling Smørgrav  *
15b7579f77SDag-Erling Smørgrav  * Redistributions in binary form must reproduce the above copyright notice,
16b7579f77SDag-Erling Smørgrav  * this list of conditions and the following disclaimer in the documentation
17b7579f77SDag-Erling Smørgrav  * and/or other materials provided with the distribution.
18b7579f77SDag-Erling Smørgrav  *
19b7579f77SDag-Erling Smørgrav  * Neither the name of the NLNET LABS nor the names of its contributors may
20b7579f77SDag-Erling Smørgrav  * be used to endorse or promote products derived from this software without
21b7579f77SDag-Erling Smørgrav  * specific prior written permission.
22b7579f77SDag-Erling Smørgrav  *
23b7579f77SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2417d15b25SDag-Erling Smørgrav  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2517d15b25SDag-Erling Smørgrav  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2617d15b25SDag-Erling Smørgrav  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2717d15b25SDag-Erling Smørgrav  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2817d15b25SDag-Erling Smørgrav  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
2917d15b25SDag-Erling Smørgrav  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3017d15b25SDag-Erling Smørgrav  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3117d15b25SDag-Erling Smørgrav  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3217d15b25SDag-Erling Smørgrav  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3317d15b25SDag-Erling Smørgrav  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34b7579f77SDag-Erling Smørgrav  */
35b7579f77SDag-Erling Smørgrav 
36b7579f77SDag-Erling Smørgrav #ifndef UTIL_LOCKS_H
37b7579f77SDag-Erling Smørgrav #define UTIL_LOCKS_H
38b7579f77SDag-Erling Smørgrav 
39b7579f77SDag-Erling Smørgrav /**
40b7579f77SDag-Erling Smørgrav  * \file
41b7579f77SDag-Erling Smørgrav  * Locking primitives.
42b7579f77SDag-Erling Smørgrav  * If pthreads is available, these are used.
43b7579f77SDag-Erling Smørgrav  * If no locking exists, they do nothing.
44b7579f77SDag-Erling Smørgrav  *
45b7579f77SDag-Erling Smørgrav  * The idea is to have different sorts of locks for different tasks.
46b7579f77SDag-Erling Smørgrav  * This allows the locking code to be ported more easily.
47b7579f77SDag-Erling Smørgrav  *
48b7579f77SDag-Erling Smørgrav  * Types of locks that are supported.
49b7579f77SDag-Erling Smørgrav  *   o lock_rw: lock that has many readers and one writer (to a data entry).
50b7579f77SDag-Erling Smørgrav  *   o lock_basic: simple mutex. Blocking, one person has access only.
51b7579f77SDag-Erling Smørgrav  *     This lock is meant for non performance sensitive uses.
52b7579f77SDag-Erling Smørgrav  *   o lock_quick: speed lock. For performance sensitive locking of critical
53b7579f77SDag-Erling Smørgrav  *     sections. Could be implemented by a mutex or a spinlock.
54b7579f77SDag-Erling Smørgrav  *
55b7579f77SDag-Erling Smørgrav  * Also thread creation and deletion functions are defined here.
56b7579f77SDag-Erling Smørgrav  */
57b7579f77SDag-Erling Smørgrav 
58ff825849SDag-Erling Smørgrav /* if you define your own LOCKRET before including locks.h, you can get most
59ff825849SDag-Erling Smørgrav  * locking functions without the dependency on log_err. */
60ff825849SDag-Erling Smørgrav #ifndef LOCKRET
61b7579f77SDag-Erling Smørgrav #include "util/log.h"
62b7579f77SDag-Erling Smørgrav /**
63b7579f77SDag-Erling Smørgrav  * The following macro is used to check the return value of the
64b7579f77SDag-Erling Smørgrav  * pthread calls. They return 0 on success and an errno on error.
65b7579f77SDag-Erling Smørgrav  * The errno is logged to the logfile with a descriptive comment.
66b7579f77SDag-Erling Smørgrav  */
67b7579f77SDag-Erling Smørgrav #define LOCKRET(func) do {\
68b7579f77SDag-Erling Smørgrav 	int lockret_err;		\
69b7579f77SDag-Erling Smørgrav 	if( (lockret_err=(func)) != 0)		\
70b7579f77SDag-Erling Smørgrav 		log_err("%s at %d could not " #func ": %s", \
71b7579f77SDag-Erling Smørgrav 		__FILE__, __LINE__, strerror(lockret_err));	\
72b7579f77SDag-Erling Smørgrav  	} while(0)
73ff825849SDag-Erling Smørgrav #endif
74b7579f77SDag-Erling Smørgrav 
75b7579f77SDag-Erling Smørgrav /** DEBUG: use thread debug whenever possible */
76b7579f77SDag-Erling Smørgrav #if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_SPINLOCK_T) && defined(ENABLE_LOCK_CHECKS)
77b7579f77SDag-Erling Smørgrav #  define USE_THREAD_DEBUG
78b7579f77SDag-Erling Smørgrav #endif
79b7579f77SDag-Erling Smørgrav 
80b7579f77SDag-Erling Smørgrav #ifdef USE_THREAD_DEBUG
81b7579f77SDag-Erling Smørgrav /******************* THREAD DEBUG ************************/
82b7579f77SDag-Erling Smørgrav /* (some) checking; to detect races and deadlocks. */
83b7579f77SDag-Erling Smørgrav #include "testcode/checklocks.h"
84b7579f77SDag-Erling Smørgrav 
85b7579f77SDag-Erling Smørgrav #else /* USE_THREAD_DEBUG */
86b7579f77SDag-Erling Smørgrav #define lock_protect(lock, area, size) /* nop */
87b7579f77SDag-Erling Smørgrav #define lock_unprotect(lock, area) /* nop */
88b7579f77SDag-Erling Smørgrav #define lock_get_mem(lock) (0) /* nothing */
89b7579f77SDag-Erling Smørgrav #define checklock_start() /* nop */
90b7579f77SDag-Erling Smørgrav #define checklock_stop() /* nop */
91b7579f77SDag-Erling Smørgrav 
92b7579f77SDag-Erling Smørgrav #ifdef HAVE_PTHREAD
93b7579f77SDag-Erling Smørgrav #include <pthread.h>
94b7579f77SDag-Erling Smørgrav 
95b7579f77SDag-Erling Smørgrav /******************* PTHREAD ************************/
96b7579f77SDag-Erling Smørgrav 
97b7579f77SDag-Erling Smørgrav /** use pthread mutex for basic lock */
98*3005e0a3SDag-Erling Smørgrav typedef pthread_mutex_t lock_basic_type;
99b7579f77SDag-Erling Smørgrav /** small front for pthread init func, NULL is default attrs. */
100b7579f77SDag-Erling Smørgrav #define lock_basic_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
101b7579f77SDag-Erling Smørgrav #define lock_basic_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
102b7579f77SDag-Erling Smørgrav #define lock_basic_lock(lock) LOCKRET(pthread_mutex_lock(lock))
103b7579f77SDag-Erling Smørgrav #define lock_basic_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
104b7579f77SDag-Erling Smørgrav 
105b7579f77SDag-Erling Smørgrav #ifndef HAVE_PTHREAD_RWLOCK_T
106b7579f77SDag-Erling Smørgrav /** in case rwlocks are not supported, use a mutex. */
107*3005e0a3SDag-Erling Smørgrav typedef pthread_mutex_t lock_rw_type;
108b7579f77SDag-Erling Smørgrav #define lock_rw_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
109b7579f77SDag-Erling Smørgrav #define lock_rw_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
110b7579f77SDag-Erling Smørgrav #define lock_rw_rdlock(lock) LOCKRET(pthread_mutex_lock(lock))
111b7579f77SDag-Erling Smørgrav #define lock_rw_wrlock(lock) LOCKRET(pthread_mutex_lock(lock))
112b7579f77SDag-Erling Smørgrav #define lock_rw_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
113b7579f77SDag-Erling Smørgrav #else /* HAVE_PTHREAD_RWLOCK_T */
114b7579f77SDag-Erling Smørgrav /** we use the pthread rwlock */
115*3005e0a3SDag-Erling Smørgrav typedef pthread_rwlock_t lock_rw_type;
116b7579f77SDag-Erling Smørgrav /** small front for pthread init func, NULL is default attrs. */
117b7579f77SDag-Erling Smørgrav #define lock_rw_init(lock) LOCKRET(pthread_rwlock_init(lock, NULL))
118b7579f77SDag-Erling Smørgrav #define lock_rw_destroy(lock) LOCKRET(pthread_rwlock_destroy(lock))
119b7579f77SDag-Erling Smørgrav #define lock_rw_rdlock(lock) LOCKRET(pthread_rwlock_rdlock(lock))
120b7579f77SDag-Erling Smørgrav #define lock_rw_wrlock(lock) LOCKRET(pthread_rwlock_wrlock(lock))
121b7579f77SDag-Erling Smørgrav #define lock_rw_unlock(lock) LOCKRET(pthread_rwlock_unlock(lock))
122b7579f77SDag-Erling Smørgrav #endif /* HAVE_PTHREAD_RWLOCK_T */
123b7579f77SDag-Erling Smørgrav 
124b7579f77SDag-Erling Smørgrav #ifndef HAVE_PTHREAD_SPINLOCK_T
125b7579f77SDag-Erling Smørgrav /** in case spinlocks are not supported, use a mutex. */
126*3005e0a3SDag-Erling Smørgrav typedef pthread_mutex_t lock_quick_type;
127b7579f77SDag-Erling Smørgrav /** small front for pthread init func, NULL is default attrs. */
128b7579f77SDag-Erling Smørgrav #define lock_quick_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
129b7579f77SDag-Erling Smørgrav #define lock_quick_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
130b7579f77SDag-Erling Smørgrav #define lock_quick_lock(lock) LOCKRET(pthread_mutex_lock(lock))
131b7579f77SDag-Erling Smørgrav #define lock_quick_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
132b7579f77SDag-Erling Smørgrav 
133b7579f77SDag-Erling Smørgrav #else /* HAVE_PTHREAD_SPINLOCK_T */
134b7579f77SDag-Erling Smørgrav /** use pthread spinlock for the quick lock */
135*3005e0a3SDag-Erling Smørgrav typedef pthread_spinlock_t lock_quick_type;
136b7579f77SDag-Erling Smørgrav /**
137b7579f77SDag-Erling Smørgrav  * allocate process private since this is available whether
138b7579f77SDag-Erling Smørgrav  * Thread Process-Shared Synchronization is supported or not.
139b7579f77SDag-Erling Smørgrav  * This means only threads inside this process may access the lock.
140b7579f77SDag-Erling Smørgrav  * (not threads from another process that shares memory).
141b7579f77SDag-Erling Smørgrav  * spinlocks are not supported on all pthread platforms.
142b7579f77SDag-Erling Smørgrav  */
143b7579f77SDag-Erling Smørgrav #define lock_quick_init(lock) LOCKRET(pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE))
144b7579f77SDag-Erling Smørgrav #define lock_quick_destroy(lock) LOCKRET(pthread_spin_destroy(lock))
145b7579f77SDag-Erling Smørgrav #define lock_quick_lock(lock) LOCKRET(pthread_spin_lock(lock))
146b7579f77SDag-Erling Smørgrav #define lock_quick_unlock(lock) LOCKRET(pthread_spin_unlock(lock))
147b7579f77SDag-Erling Smørgrav 
148b7579f77SDag-Erling Smørgrav #endif /* HAVE SPINLOCK */
149b7579f77SDag-Erling Smørgrav 
150b7579f77SDag-Erling Smørgrav /** Thread creation */
151*3005e0a3SDag-Erling Smørgrav typedef pthread_t ub_thread_type;
152*3005e0a3SDag-Erling Smørgrav /** On alpine linux default thread stack size is 80 Kb. See
153*3005e0a3SDag-Erling Smørgrav http://wiki.musl-libc.org/wiki/Functional_differences_from_glibc#Thread_stack_size
154*3005e0a3SDag-Erling Smørgrav This is not enough and cause segfault. Other linux distros have 2 Mb at least.
155*3005e0a3SDag-Erling Smørgrav Wrapper for set up thread stack size */
156*3005e0a3SDag-Erling Smørgrav #define PTHREADSTACKSIZE 2*1024*1024
157*3005e0a3SDag-Erling Smørgrav #define PTHREADCREATE(thr, stackrequired, func, arg) do {\
158*3005e0a3SDag-Erling Smørgrav 	pthread_attr_t attr; \
159*3005e0a3SDag-Erling Smørgrav 	size_t stacksize; \
160*3005e0a3SDag-Erling Smørgrav 	LOCKRET(pthread_attr_init(&attr)); \
161*3005e0a3SDag-Erling Smørgrav 	LOCKRET(pthread_attr_getstacksize(&attr, &stacksize)); \
162*3005e0a3SDag-Erling Smørgrav 	if (stacksize < stackrequired) { \
163*3005e0a3SDag-Erling Smørgrav 		LOCKRET(pthread_attr_setstacksize(&attr, stackrequired)); \
164*3005e0a3SDag-Erling Smørgrav 		LOCKRET(pthread_create(thr, &attr, func, arg)); \
165*3005e0a3SDag-Erling Smørgrav 		LOCKRET(pthread_attr_getstacksize(&attr, &stacksize)); \
166*3005e0a3SDag-Erling Smørgrav 		verbose(VERB_ALGO, "Thread stack size set to %u", (unsigned)stacksize); \
167*3005e0a3SDag-Erling Smørgrav 	} else {LOCKRET(pthread_create(thr, NULL, func, arg));} \
168*3005e0a3SDag-Erling Smørgrav 	} while(0)
169*3005e0a3SDag-Erling Smørgrav /** Use wrapper for set thread stack size on attributes. */
170*3005e0a3SDag-Erling Smørgrav #define ub_thread_create(thr, func, arg) PTHREADCREATE(thr, PTHREADSTACKSIZE, func, arg)
171b7579f77SDag-Erling Smørgrav /** get self id. */
172b7579f77SDag-Erling Smørgrav #define ub_thread_self() pthread_self()
173b7579f77SDag-Erling Smørgrav /** wait for another thread to terminate */
174b7579f77SDag-Erling Smørgrav #define ub_thread_join(thread) LOCKRET(pthread_join(thread, NULL))
175*3005e0a3SDag-Erling Smørgrav typedef pthread_key_t ub_thread_key_type;
176b7579f77SDag-Erling Smørgrav #define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
177b7579f77SDag-Erling Smørgrav #define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
178b7579f77SDag-Erling Smørgrav #define ub_thread_key_get(key) pthread_getspecific(key)
179b7579f77SDag-Erling Smørgrav 
180b7579f77SDag-Erling Smørgrav #else /* we do not HAVE_PTHREAD */
181b7579f77SDag-Erling Smørgrav #ifdef HAVE_SOLARIS_THREADS
182b7579f77SDag-Erling Smørgrav 
183b7579f77SDag-Erling Smørgrav /******************* SOLARIS THREADS ************************/
184b7579f77SDag-Erling Smørgrav #include <synch.h>
185b7579f77SDag-Erling Smørgrav #include <thread.h>
186b7579f77SDag-Erling Smørgrav 
187*3005e0a3SDag-Erling Smørgrav typedef rwlock_t lock_rw_type;
188b7579f77SDag-Erling Smørgrav #define lock_rw_init(lock) LOCKRET(rwlock_init(lock, USYNC_THREAD, NULL))
189b7579f77SDag-Erling Smørgrav #define lock_rw_destroy(lock) LOCKRET(rwlock_destroy(lock))
190b7579f77SDag-Erling Smørgrav #define lock_rw_rdlock(lock) LOCKRET(rw_rdlock(lock))
191b7579f77SDag-Erling Smørgrav #define lock_rw_wrlock(lock) LOCKRET(rw_wrlock(lock))
192b7579f77SDag-Erling Smørgrav #define lock_rw_unlock(lock) LOCKRET(rw_unlock(lock))
193b7579f77SDag-Erling Smørgrav 
194b7579f77SDag-Erling Smørgrav /** use basic mutex */
195*3005e0a3SDag-Erling Smørgrav typedef mutex_t lock_basic_type;
196b7579f77SDag-Erling Smørgrav #define lock_basic_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
197b7579f77SDag-Erling Smørgrav #define lock_basic_destroy(lock) LOCKRET(mutex_destroy(lock))
198b7579f77SDag-Erling Smørgrav #define lock_basic_lock(lock) LOCKRET(mutex_lock(lock))
199b7579f77SDag-Erling Smørgrav #define lock_basic_unlock(lock) LOCKRET(mutex_unlock(lock))
200b7579f77SDag-Erling Smørgrav 
201b7579f77SDag-Erling Smørgrav /** No spinlocks in solaris threads API. Use a mutex. */
202*3005e0a3SDag-Erling Smørgrav typedef mutex_t lock_quick_type;
203b7579f77SDag-Erling Smørgrav #define lock_quick_init(lock) LOCKRET(mutex_init(lock, USYNC_THREAD, NULL))
204b7579f77SDag-Erling Smørgrav #define lock_quick_destroy(lock) LOCKRET(mutex_destroy(lock))
205b7579f77SDag-Erling Smørgrav #define lock_quick_lock(lock) LOCKRET(mutex_lock(lock))
206b7579f77SDag-Erling Smørgrav #define lock_quick_unlock(lock) LOCKRET(mutex_unlock(lock))
207b7579f77SDag-Erling Smørgrav 
208b7579f77SDag-Erling Smørgrav /** Thread creation, create a default thread. */
209*3005e0a3SDag-Erling Smørgrav typedef thread_t ub_thread_type;
210b7579f77SDag-Erling Smørgrav #define ub_thread_create(thr, func, arg) LOCKRET(thr_create(NULL, NULL, func, arg, NULL, thr))
211b7579f77SDag-Erling Smørgrav #define ub_thread_self() thr_self()
212b7579f77SDag-Erling Smørgrav #define ub_thread_join(thread) LOCKRET(thr_join(thread, NULL, NULL))
213*3005e0a3SDag-Erling Smørgrav typedef thread_key_t ub_thread_key_type;
214b7579f77SDag-Erling Smørgrav #define ub_thread_key_create(key, f) LOCKRET(thr_keycreate(key, f))
215b7579f77SDag-Erling Smørgrav #define ub_thread_key_set(key, v) LOCKRET(thr_setspecific(key, v))
216*3005e0a3SDag-Erling Smørgrav void* ub_thread_key_get(ub_thread_key_type key);
217b7579f77SDag-Erling Smørgrav 
218b7579f77SDag-Erling Smørgrav 
219b7579f77SDag-Erling Smørgrav #else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */
220b7579f77SDag-Erling Smørgrav /******************* WINDOWS THREADS ************************/
221b7579f77SDag-Erling Smørgrav #ifdef HAVE_WINDOWS_THREADS
222b7579f77SDag-Erling Smørgrav #include <windows.h>
223b7579f77SDag-Erling Smørgrav 
224b7579f77SDag-Erling Smørgrav /* Use a mutex */
225*3005e0a3SDag-Erling Smørgrav typedef LONG lock_rw_type;
226b7579f77SDag-Erling Smørgrav #define lock_rw_init(lock) lock_basic_init(lock)
227b7579f77SDag-Erling Smørgrav #define lock_rw_destroy(lock) lock_basic_destroy(lock)
228b7579f77SDag-Erling Smørgrav #define lock_rw_rdlock(lock) lock_basic_lock(lock)
229b7579f77SDag-Erling Smørgrav #define lock_rw_wrlock(lock) lock_basic_lock(lock)
230b7579f77SDag-Erling Smørgrav #define lock_rw_unlock(lock) lock_basic_unlock(lock)
231b7579f77SDag-Erling Smørgrav 
232b7579f77SDag-Erling Smørgrav /** the basic lock is a mutex, implemented opaquely, for error handling. */
233*3005e0a3SDag-Erling Smørgrav typedef LONG lock_basic_type;
234*3005e0a3SDag-Erling Smørgrav void lock_basic_init(lock_basic_type* lock);
235*3005e0a3SDag-Erling Smørgrav void lock_basic_destroy(lock_basic_type* lock);
236*3005e0a3SDag-Erling Smørgrav void lock_basic_lock(lock_basic_type* lock);
237*3005e0a3SDag-Erling Smørgrav void lock_basic_unlock(lock_basic_type* lock);
238b7579f77SDag-Erling Smørgrav 
239b7579f77SDag-Erling Smørgrav /** on windows no spinlock, use mutex too. */
240*3005e0a3SDag-Erling Smørgrav typedef LONG lock_quick_type;
241b7579f77SDag-Erling Smørgrav #define lock_quick_init(lock) lock_basic_init(lock)
242b7579f77SDag-Erling Smørgrav #define lock_quick_destroy(lock) lock_basic_destroy(lock)
243b7579f77SDag-Erling Smørgrav #define lock_quick_lock(lock) lock_basic_lock(lock)
244b7579f77SDag-Erling Smørgrav #define lock_quick_unlock(lock) lock_basic_unlock(lock)
245b7579f77SDag-Erling Smørgrav 
246b7579f77SDag-Erling Smørgrav /** Thread creation, create a default thread. */
247*3005e0a3SDag-Erling Smørgrav typedef HANDLE ub_thread_type;
248*3005e0a3SDag-Erling Smørgrav void ub_thread_create(ub_thread_type* thr, void* (*func)(void*), void* arg);
249*3005e0a3SDag-Erling Smørgrav ub_thread_type ub_thread_self(void);
250*3005e0a3SDag-Erling Smørgrav void ub_thread_join(ub_thread_type thr);
251*3005e0a3SDag-Erling Smørgrav typedef DWORD ub_thread_key_type;
252*3005e0a3SDag-Erling Smørgrav void ub_thread_key_create(ub_thread_key_type* key, void* f);
253*3005e0a3SDag-Erling Smørgrav void ub_thread_key_set(ub_thread_key_type key, void* v);
254*3005e0a3SDag-Erling Smørgrav void* ub_thread_key_get(ub_thread_key_type key);
255b7579f77SDag-Erling Smørgrav 
256b7579f77SDag-Erling Smørgrav #else /* we do not HAVE_SOLARIS_THREADS, PTHREADS or WINDOWS_THREADS */
257b7579f77SDag-Erling Smørgrav 
258b7579f77SDag-Erling Smørgrav /******************* NO THREADS ************************/
259b7579f77SDag-Erling Smørgrav #define THREADS_DISABLED 1
260b7579f77SDag-Erling Smørgrav /** In case there is no thread support, define locks to do nothing */
261*3005e0a3SDag-Erling Smørgrav typedef int lock_rw_type;
262b7579f77SDag-Erling Smørgrav #define lock_rw_init(lock) /* nop */
263b7579f77SDag-Erling Smørgrav #define lock_rw_destroy(lock) /* nop */
264b7579f77SDag-Erling Smørgrav #define lock_rw_rdlock(lock) /* nop */
265b7579f77SDag-Erling Smørgrav #define lock_rw_wrlock(lock) /* nop */
266b7579f77SDag-Erling Smørgrav #define lock_rw_unlock(lock) /* nop */
267b7579f77SDag-Erling Smørgrav 
268b7579f77SDag-Erling Smørgrav /** define locks to do nothing */
269*3005e0a3SDag-Erling Smørgrav typedef int lock_basic_type;
270b7579f77SDag-Erling Smørgrav #define lock_basic_init(lock) /* nop */
271b7579f77SDag-Erling Smørgrav #define lock_basic_destroy(lock) /* nop */
272b7579f77SDag-Erling Smørgrav #define lock_basic_lock(lock) /* nop */
273b7579f77SDag-Erling Smørgrav #define lock_basic_unlock(lock) /* nop */
274b7579f77SDag-Erling Smørgrav 
275b7579f77SDag-Erling Smørgrav /** define locks to do nothing */
276*3005e0a3SDag-Erling Smørgrav typedef int lock_quick_type;
277b7579f77SDag-Erling Smørgrav #define lock_quick_init(lock) /* nop */
278b7579f77SDag-Erling Smørgrav #define lock_quick_destroy(lock) /* nop */
279b7579f77SDag-Erling Smørgrav #define lock_quick_lock(lock) /* nop */
280b7579f77SDag-Erling Smørgrav #define lock_quick_unlock(lock) /* nop */
281b7579f77SDag-Erling Smørgrav 
282b7579f77SDag-Erling Smørgrav /** Thread creation, threads do not exist */
283*3005e0a3SDag-Erling Smørgrav typedef pid_t ub_thread_type;
284b7579f77SDag-Erling Smørgrav /** ub_thread_create is simulated with fork (extremely heavy threads,
285b7579f77SDag-Erling Smørgrav   * with no shared memory). */
286b7579f77SDag-Erling Smørgrav #define ub_thread_create(thr, func, arg) \
287b7579f77SDag-Erling Smørgrav 	ub_thr_fork_create(thr, func, arg)
288b7579f77SDag-Erling Smørgrav #define ub_thread_self() getpid()
289b7579f77SDag-Erling Smørgrav #define ub_thread_join(thread) ub_thr_fork_wait(thread)
290*3005e0a3SDag-Erling Smørgrav void ub_thr_fork_wait(ub_thread_type thread);
291*3005e0a3SDag-Erling Smørgrav void ub_thr_fork_create(ub_thread_type* thr, void* (*func)(void*), void* arg);
292*3005e0a3SDag-Erling Smørgrav typedef void* ub_thread_key_type;
293b7579f77SDag-Erling Smørgrav #define ub_thread_key_create(key, f) (*(key)) = NULL
294b7579f77SDag-Erling Smørgrav #define ub_thread_key_set(key, v) (key) = (v)
295b7579f77SDag-Erling Smørgrav #define ub_thread_key_get(key) (key)
296b7579f77SDag-Erling Smørgrav 
297b7579f77SDag-Erling Smørgrav #endif /* HAVE_WINDOWS_THREADS */
298b7579f77SDag-Erling Smørgrav #endif /* HAVE_SOLARIS_THREADS */
299b7579f77SDag-Erling Smørgrav #endif /* HAVE_PTHREAD */
300b7579f77SDag-Erling Smørgrav #endif /* USE_THREAD_DEBUG */
301b7579f77SDag-Erling Smørgrav 
302b7579f77SDag-Erling Smørgrav /**
303b7579f77SDag-Erling Smørgrav  * Block all signals for this thread.
304b7579f77SDag-Erling Smørgrav  * fatal exit on error.
305b7579f77SDag-Erling Smørgrav  */
306b7579f77SDag-Erling Smørgrav void ub_thread_blocksigs(void);
307b7579f77SDag-Erling Smørgrav 
308b7579f77SDag-Erling Smørgrav /**
309b7579f77SDag-Erling Smørgrav  * unblock one signal for this thread.
310b7579f77SDag-Erling Smørgrav  */
311b7579f77SDag-Erling Smørgrav void ub_thread_sig_unblock(int sig);
312b7579f77SDag-Erling Smørgrav 
313b7579f77SDag-Erling Smørgrav #endif /* UTIL_LOCKS_H */
314