diff options
Diffstat (limited to 'src/libstrongswan/threading')
-rw-r--r-- | src/libstrongswan/threading/condvar.c | 19 | ||||
-rw-r--r-- | src/libstrongswan/threading/condvar.h | 75 | ||||
-rw-r--r-- | src/libstrongswan/threading/mutex.c | 51 | ||||
-rw-r--r-- | src/libstrongswan/threading/mutex.h | 90 | ||||
-rw-r--r-- | src/libstrongswan/threading/rwlock.c | 63 | ||||
-rw-r--r-- | src/libstrongswan/threading/rwlock.h | 82 |
6 files changed, 293 insertions, 87 deletions
diff --git a/src/libstrongswan/threading/condvar.c b/src/libstrongswan/threading/condvar.c index 7ba1c07ec..4c9589081 100644 --- a/src/libstrongswan/threading/condvar.c +++ b/src/libstrongswan/threading/condvar.c @@ -20,13 +20,30 @@ #include <time.h> #include <errno.h> -#include <threading.h> #include <library.h> #include <debug.h> #include "condvar.h" #include "mutex.h" +typedef struct private_condvar_t private_condvar_t; + +/** + * private data of condvar + */ +struct private_condvar_t { + + /** + * public functions + */ + condvar_t public; + + /** + * wrapped pthread condvar + */ + pthread_cond_t condvar; +}; + /** * Implementation of condvar_t.wait. */ diff --git a/src/libstrongswan/threading/condvar.h b/src/libstrongswan/threading/condvar.h index 9b2966253..48c949c7c 100644 --- a/src/libstrongswan/threading/condvar.h +++ b/src/libstrongswan/threading/condvar.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2009 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -14,26 +14,83 @@ * for more details. */ +/** + * @defgroup condvar condvar + * @{ @ingroup threading + */ + #ifndef THREADING_CONDVAR_H_ #define THREADING_CONDVAR_H_ -typedef struct private_condvar_t private_condvar_t; +typedef struct condvar_t condvar_t; +typedef enum condvar_type_t condvar_type_t; + +#include "mutex.h" + +/** + * Type of condvar. + */ +enum condvar_type_t { + /** default condvar */ + CONDVAR_TYPE_DEFAULT = 0, +}; /** - * private data of condvar + * Condvar wrapper to use in conjunction with mutex_t. */ -struct private_condvar_t { +struct condvar_t { + + /** + * Wait on a condvar until it gets signalized. + * + * @param mutex mutex to release while waiting + */ + void (*wait)(condvar_t *this, mutex_t *mutex); + + /** + * Wait on a condvar until it gets signalized, or times out. + * + * @param mutex mutex to release while waiting + * @param timeout timeout im ms + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait)(condvar_t *this, mutex_t *mutex, u_int timeout); + + /** + * Wait on a condvar until it gets signalized, or times out. + * + * The passed timeval should be calculated based on the time_monotonic() + * function. + * + * @param mutex mutex to release while waiting + * @param tv absolute time until timeout + * @return TRUE if timed out, FALSE otherwise + */ + bool (*timed_wait_abs)(condvar_t *this, mutex_t *mutex, timeval_t tv); + + /** + * Wake up a single thread in a condvar. + */ + void (*signal)(condvar_t *this); /** - * public functions + * Wake up all threads in a condvar. */ - condvar_t public; + void (*broadcast)(condvar_t *this); /** - * wrapped pthread condvar + * Destroy a condvar and free its resources. */ - pthread_cond_t condvar; + void (*destroy)(condvar_t *this); }; -#endif /* THREADING_CONDVAR_H_ */ +/** + * Create a condvar instance. + * + * @param type type of condvar to create + * @return condvar instance + */ +condvar_t *condvar_create(condvar_type_t type); + +#endif /** THREADING_CONDVAR_H_ @} */ diff --git a/src/libstrongswan/threading/mutex.c b/src/libstrongswan/threading/mutex.c index a3d131a05..6133822c3 100644 --- a/src/libstrongswan/threading/mutex.c +++ b/src/libstrongswan/threading/mutex.c @@ -17,13 +17,62 @@ #define _GNU_SOURCE #include <pthread.h> -#include <threading.h> #include <library.h> #include <debug.h> #include "mutex.h" #include "lock_profiler.h" +typedef struct private_mutex_t private_mutex_t; +typedef struct private_r_mutex_t private_r_mutex_t; + +/** + * private data of mutex + */ +struct private_mutex_t { + + /** + * public functions + */ + mutex_t public; + + /** + * wrapped pthread mutex + */ + pthread_mutex_t mutex; + + /** + * is this a recursiv emutex, implementing private_r_mutex_t? + */ + bool recursive; + + /** + * profiling info, if enabled + */ + lock_profile_t profile; +}; + +/** + * private data of mutex, extended by recursive locking information + */ +struct private_r_mutex_t { + + /** + * Extends private_mutex_t + */ + private_mutex_t generic; + + /** + * thread which currently owns mutex + */ + pthread_t thread; + + /** + * times we have locked the lock, stored per thread + */ + pthread_key_t times; +}; + /** * Implementation of mutex_t.lock. */ diff --git a/src/libstrongswan/threading/mutex.h b/src/libstrongswan/threading/mutex.h index 50c066045..ca242f680 100644 --- a/src/libstrongswan/threading/mutex.h +++ b/src/libstrongswan/threading/mutex.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2009 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -14,60 +14,84 @@ * for more details. */ +/** + * @defgroup mutex mutex + * @{ @ingroup threading + */ + #ifndef THREADING_MUTEX_H_ #define THREADING_MUTEX_H_ -#include "lock_profiler.h" +typedef struct mutex_t mutex_t; +typedef enum mutex_type_t mutex_type_t; -typedef struct private_mutex_t private_mutex_t; -typedef struct private_r_mutex_t private_r_mutex_t; +#include "condvar.h" -/** - * private data of mutex +#ifdef __APPLE__ +/* on Mac OS X 10.5 several system calls we use are no cancellation points. + * fortunately, select isn't one of them, so we wrap some of the others with + * calls to select(2). */ -struct private_mutex_t { +#include <sys/socket.h> +#include <sys/select.h> - /** - * public functions - */ - mutex_t public; +#define WRAP_WITH_SELECT(func, socket, ...)\ + fd_set rfds; FD_ZERO(&rfds); FD_SET(socket, &rfds);\ + if (select(socket + 1, &rfds, NULL, NULL, NULL) <= 0) { return -1; }\ + return func(socket, __VA_ARGS__) - /** - * wrapped pthread mutex - */ - pthread_mutex_t mutex; +static inline int cancellable_accept(int socket, struct sockaddr *address, + socklen_t *address_len) +{ + WRAP_WITH_SELECT(accept, socket, address, address_len); +} +#define accept cancellable_accept +static inline int cancellable_recvfrom(int socket, void *buffer, size_t length, + int flags, struct sockaddr *address, socklen_t *address_len) +{ + WRAP_WITH_SELECT(recvfrom, socket, buffer, length, flags, address, address_len); +} +#define recvfrom cancellable_recvfrom +#endif /* __APPLE__ */ - /** - * is this a recursiv emutex, implementing private_r_mutex_t? - */ - bool recursive; - - /** - * profiling info, if enabled - */ - lock_profile_t profile; +/** + * Type of mutex. + */ +enum mutex_type_t { + /** default mutex */ + MUTEX_TYPE_DEFAULT = 0, + /** allow recursive locking of the mutex */ + MUTEX_TYPE_RECURSIVE = 1, }; /** - * private data of mutex, extended by recursive locking information + * Mutex wrapper implements simple, portable and advanced mutex functions. */ -struct private_r_mutex_t { +struct mutex_t { /** - * Extends private_mutex_t + * Acquire the lock to the mutex. */ - private_mutex_t generic; + void (*lock)(mutex_t *this); /** - * thread which currently owns mutex + * Release the lock on the mutex. */ - pthread_t thread; + void (*unlock)(mutex_t *this); /** - * times we have locked the lock, stored per thread + * Destroy a mutex instance. */ - pthread_key_t times; + void (*destroy)(mutex_t *this); }; -#endif /* THREADING_MUTEX_H_ */ +/** + * Create a mutex instance. + * + * @param type type of mutex to create + * @return unlocked mutex instance + */ +mutex_t *mutex_create(mutex_type_t type); + +#endif /** THREADING_MUTEX_H_ @} */ diff --git a/src/libstrongswan/threading/rwlock.c b/src/libstrongswan/threading/rwlock.c index bf59f50f1..ee9fb10be 100644 --- a/src/libstrongswan/threading/rwlock.c +++ b/src/libstrongswan/threading/rwlock.c @@ -17,13 +17,74 @@ #define _GNU_SOURCE #include <pthread.h> -#include <threading.h> #include <library.h> #include <debug.h> #include "rwlock.h" +#include "condvar.h" +#include "mutex.h" #include "lock_profiler.h" +typedef struct private_rwlock_t private_rwlock_t; + +/** + * private data of rwlock + */ +struct private_rwlock_t { + + /** + * public functions + */ + rwlock_t public; + +#ifdef HAVE_PTHREAD_RWLOCK_INIT + + /** + * wrapped pthread rwlock + */ + pthread_rwlock_t rwlock; + +#else + + /** + * mutex to emulate a native rwlock + */ + mutex_t *mutex; + + /** + * condvar to handle writers + */ + condvar_t *writers; + + /** + * condvar to handle readers + */ + condvar_t *readers; + + /** + * number of waiting writers + */ + u_int waiting_writers; + + /** + * number of readers holding the lock + */ + u_int reader_count; + + /** + * current writer thread, if any + */ + pthread_t writer; + +#endif /* HAVE_PTHREAD_RWLOCK_INIT */ + + /** + * profiling info, if enabled + */ + lock_profile_t profile; +}; + + #ifdef HAVE_PTHREAD_RWLOCK_INIT /** diff --git a/src/libstrongswan/threading/rwlock.h b/src/libstrongswan/threading/rwlock.h index 2f4330ffb..a86a241c5 100644 --- a/src/libstrongswan/threading/rwlock.h +++ b/src/libstrongswan/threading/rwlock.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008-2009 Tobias Brunner * Copyright (C) 2008 Martin Willi * Hochschule fuer Technik Rapperswil * @@ -14,69 +14,67 @@ * for more details. */ +/** + * @defgroup rwlock rwlock + * @{ @ingroup threading + */ + #ifndef THREADING_RWLOCK_H_ #define THREADING_RWLOCK_H_ -#include "lock_profiler.h" - -typedef struct private_rwlock_t private_rwlock_t; +typedef struct rwlock_t rwlock_t; +typedef enum rwlock_type_t rwlock_type_t; /** - * private data of rwlock + * Type of read-write lock. */ -struct private_rwlock_t { - - /** - * public functions - */ - rwlock_t public; - -#ifdef HAVE_PTHREAD_RWLOCK_INIT - - /** - * wrapped pthread rwlock - */ - pthread_rwlock_t rwlock; - -#else - - /** - * mutex to emulate a native rwlock - */ - mutex_t *mutex; +enum rwlock_type_t { + /** default condvar */ + RWLOCK_TYPE_DEFAULT = 0, +}; - /** - * condvar to handle writers - */ - condvar_t *writers; +/** + * Read-Write lock wrapper. + */ +struct rwlock_t { /** - * condvar to handle readers + * Acquire the read lock. */ - condvar_t *readers; + void (*read_lock)(rwlock_t *this); /** - * number of waiting writers + * Acquire the write lock. */ - u_int waiting_writers; + void (*write_lock)(rwlock_t *this); /** - * number of readers holding the lock + * Try to acquire the write lock. + * + * Never blocks, but returns FALSE if the lock was already occupied. + * + * @return TRUE if lock acquired */ - u_int reader_count; + bool (*try_write_lock)(rwlock_t *this); /** - * current writer thread, if any + * Release any acquired lock. */ - pthread_t writer; - -#endif /* HAVE_PTHREAD_RWLOCK_INIT */ + void (*unlock)(rwlock_t *this); /** - * profiling info, if enabled + * Destroy the read-write lock. */ - lock_profile_t profile; + void (*destroy)(rwlock_t *this); }; -#endif /* THREADING_THREADING_H_ */ +/** + * Create a read-write lock instance. + * + * @param type type of rwlock to create + * @return unlocked rwlock instance + */ +rwlock_t *rwlock_create(rwlock_type_t type); + +#endif /** THREADING_RWLOCK_H_ @} */ |