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