--- /dev/null
+/**
+ * util/locks.c - unbound locking primitives
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ * Implementation of locking and threading support.
+ * A place for locking debug code since most locking functions are macros.
+ */
+
+#include "config.h"
+#include "util/locks.h"
+
--- /dev/null
+/**
+ * util/locks.h - unbound locking primitives
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UTIL_LOCKS_H
+#define UTIL_LOCKS_H
+
+/**
+ * \file
+ * Locking primitives.
+ * If pthreads is available, these are used.
+ * If no locking exists, they do nothing.
+ *
+ * The idea is to have different sorts of locks for different tasks.
+ * This allows the locking code to be ported more easily.
+ *
+ * Types of locks that are supported.
+ * o lock_rw: lock that has many readers and one writer (to a data entry).
+ * o lock_basic: simple mutex. Blocking, one person has access only.
+ * This lock is meant for non performance sensitive uses.
+ * o lock_quick: speed lock. For performance sensitive locking of critical
+ * sections. Could be implemented by a mutex or a spinlock.
+ *
+ * Also thread creation and deletion functions are defined here.
+ */
+
+#include "util/log.h"
+
+/**
+ * The following macro is used to check the return value of the
+ * pthread calls. They return 0 on success and an errno on error.
+ * The errno is logged to the logfile with a descriptive comment.
+ */
+#define LOCKRET(func) do {\
+ int err; \
+ if( (err=(func)) != 0) \
+ log_err("%s at %d could not " #func ": %s", \
+ __FILE__, __LINE__, strerror(err)); \
+ } while(0)
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+
+/** we use the pthread rwlock */
+typedef pthread_rwlock_t lock_rw_t;
+/** small front for pthread init func, NULL is default attrs. */
+#define lock_rw_init(lock) LOCKRET(pthread_rwlock_init(lock, NULL))
+/** free up the lock. must be unlocked. */
+#define lock_rw_destroy(lock) LOCKRET(pthread_rwlock_destroy(lock))
+/** acquire a read lock */
+#define lock_rw_rdlock(lock) LOCKRET(pthread_rwlock_rdlock(lock))
+/** acquire a write lock */
+#define lock_rw_wrlock(lock) LOCKRET(pthread_rwlock_wrlock(lock))
+/** unlock previously acquired read or write lock */
+#define lock_rw_unlock(lock) LOCKRET(pthread_rwlock_unlock(lock))
+
+/** use pthread mutex for basic lock */
+typedef pthread_mutex_t lock_basic_t;
+/** small front for pthread init func, NULL is default attrs. */
+#define lock_basic_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
+/** free up the lock. must be unlocked. */
+#define lock_basic_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
+/** acquire lock. This may block indefinetely. */
+#define lock_basic_lock(lock) LOCKRET(pthread_mutex_lock(lock))
+/** unlock acquired lock. */
+#define lock_basic_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
+
+#ifdef HAVE_PTHREAD_SPINLOCK_T
+/** in case spinlocks are not supported, use a mutex. */
+typedef pthread_mutex_t lock_quick_t;
+/** small front for pthread init func, NULL is default attrs. */
+#define lock_quick_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
+/** free up the lock. must be unlocked. */
+#define lock_quick_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
+/** acquire lock. may block. */
+#define lock_quick_lock(lock) LOCKRET(pthread_mutex_lock(lock))
+/** unlock acquired lock. */
+#define lock_quick_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
+
+#else /* HAVE_PTHREAD_SPINLOCK_T */
+/** use pthread spinlock for the quick lock */
+typedef pthread_spinlock_t lock_quick_t;
+/**
+ * allocate process private since this is available whether
+ * Thread Process-Shared Synchronization is supported or not.
+ * This means only threads inside this process may access the lock.
+ * (not threads from another process that shares memory).
+ * spinlocks are not supported on all pthread platforms.
+ */
+#define lock_quick_init(lock) LOCKRET(pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE))
+/** free up the lock. must be unlocked. */
+#define lock_quick_destroy(lock) LOCKRET(pthread_spin_destroy(lock))
+/** acquire lock. This may block indefinetely, and will spin. */
+#define lock_quick_lock(lock) LOCKRET(pthread_spin_lock(lock))
+/** unlock acquired lock. */
+#define lock_quick_unlock(lock) LOCKRET(pthread_spin_unlock(lock))
+
+#endif /* HAVE SPINLOCK */
+
+/** Thread creation */
+typedef pthread_t ub_thread_t;
+/** Pass where to store tread_t in thr. Use default NULL attributes. */
+#define ub_thread_create(thr, func, arg) LOCKRET(pthread_create(thr, NULL, func, arg))
+
+#else /* HAVE_PTHREAD */
+
+/** In case there is no pthread support, define locks to do nothing */
+typedef int lock_rw_t;
+/** does nothing */
+#define lock_rw_init(lock) /* nop */
+/** does nothing */
+#define lock_rw_destroy(lock) /* nop */
+/** does nothing */
+#define lock_rw_rdlock(lock) /* nop */
+/** does nothing */
+#define lock_rw_wrlock(lock) /* nop */
+/** does nothing */
+#define lock_rw_unlock(lock) /* nop */
+
+/** define locks to do nothing */
+typedef int lock_basic_t;
+/** does nothing */
+#define lock_basic_init(lock) /* nop */
+/** does nothing */
+#define lock_basic_destroy(lock) /* nop */
+/** does nothing */
+#define lock_basic_lock(lock) /* nop */
+/** does nothing */
+#define lock_basic_unlock(lock) /* nop */
+
+/** define locks to do nothing */
+typedef int lock_quick_t;
+/** does nothing */
+#define lock_quick_init(lock) /* nop */
+/** does nothing */
+#define lock_quick_destroy(lock) /* nop */
+/** does nothing */
+#define lock_quick_lock(lock) /* nop */
+/** does nothing */
+#define lock_quick_unlock(lock) /* nop */
+
+/** Thread creation, threads do not exist */
+typedef int ub_thread_t;
+/** ub_thread_create gives an error, it should not be called. */
+#define ub_thread_create(thr, func, arg) \
+ fatal_exit("%s %d called thread create, but no thread support " \
+ "has been compiled in.", __FILE__, __LINE__)
+
+#endif /* HAVE_PTHREAD */
+#endif /* UTIL_LOCKS_H */