diff options
Diffstat (limited to 'src/libstrongswan/threading')
-rw-r--r-- | src/libstrongswan/threading/mutex.c | 128 | ||||
-rw-r--r-- | src/libstrongswan/threading/rwlock.c | 106 | ||||
-rw-r--r-- | src/libstrongswan/threading/thread.c | 96 | ||||
-rw-r--r-- | src/libstrongswan/threading/thread_value.c | 32 |
4 files changed, 177 insertions, 185 deletions
diff --git a/src/libstrongswan/threading/mutex.c b/src/libstrongswan/threading/mutex.c index 8597abb44..3bdb3bf29 100644 --- a/src/libstrongswan/threading/mutex.c +++ b/src/libstrongswan/threading/mutex.c @@ -96,11 +96,8 @@ struct private_condvar_t { }; - -/** - * Implementation of mutex_t.lock. - */ -static void lock(private_mutex_t *this) +METHOD(mutex_t, lock, void, + private_mutex_t *this) { int err; @@ -113,10 +110,8 @@ static void lock(private_mutex_t *this) profiler_end(&this->profile); } -/** - * Implementation of mutex_t.unlock. - */ -static void unlock(private_mutex_t *this) +METHOD(mutex_t, unlock, void, + private_mutex_t *this) { int err; @@ -127,10 +122,8 @@ static void unlock(private_mutex_t *this) } } -/** - * Implementation of mutex_t.lock. - */ -static void lock_r(private_r_mutex_t *this) +METHOD(mutex_t, lock_r, void, + private_r_mutex_t *this) { pthread_t self = pthread_self(); @@ -151,10 +144,8 @@ static void lock_r(private_r_mutex_t *this) } } -/** - * Implementation of mutex_t.unlock. - */ -static void unlock_r(private_r_mutex_t *this) +METHOD(mutex_t, unlock_r, void, + private_r_mutex_t *this) { uintptr_t times; @@ -169,20 +160,16 @@ static void unlock_r(private_r_mutex_t *this) } } -/** - * Implementation of mutex_t.destroy - */ -static void mutex_destroy(private_mutex_t *this) +METHOD(mutex_t, mutex_destroy, void, + private_mutex_t *this) { profiler_cleanup(&this->profile); pthread_mutex_destroy(&this->mutex); free(this); } -/** - * Implementation of mutex_t.destroy for recursive mutex' - */ -static void mutex_destroy_r(private_r_mutex_t *this) +METHOD(mutex_t, mutex_destroy_r, void, + private_r_mutex_t *this) { profiler_cleanup(&this->generic.profile); pthread_mutex_destroy(&this->generic.mutex); @@ -199,31 +186,39 @@ mutex_t *mutex_create(mutex_type_t type) { case MUTEX_TYPE_RECURSIVE: { - private_r_mutex_t *this = malloc_thing(private_r_mutex_t); - - this->generic.public.lock = (void(*)(mutex_t*))lock_r; - this->generic.public.unlock = (void(*)(mutex_t*))unlock_r; - this->generic.public.destroy = (void(*)(mutex_t*))mutex_destroy_r; + private_r_mutex_t *this; + + INIT(this, + .generic = { + .public = { + .lock = _lock_r, + .unlock = _unlock_r, + .destroy = _mutex_destroy_r, + }, + .recursive = TRUE, + }, + ); pthread_mutex_init(&this->generic.mutex, NULL); pthread_key_create(&this->times, NULL); - this->generic.recursive = TRUE; profiler_init(&this->generic.profile); - this->thread = 0; return &this->generic.public; } case MUTEX_TYPE_DEFAULT: default: { - private_mutex_t *this = malloc_thing(private_mutex_t); + private_mutex_t *this; - this->public.lock = (void(*)(mutex_t*))lock; - this->public.unlock = (void(*)(mutex_t*))unlock; - this->public.destroy = (void(*)(mutex_t*))mutex_destroy; + INIT(this, + .public = { + .lock = _lock, + .unlock = _unlock, + .destroy = _mutex_destroy, + }, + ); pthread_mutex_init(&this->mutex, NULL); - this->recursive = FALSE; profiler_init(&this->profile); return &this->public; @@ -232,11 +227,8 @@ mutex_t *mutex_create(mutex_type_t type) } - -/** - * Implementation of condvar_t.wait. - */ -static void _wait(private_condvar_t *this, private_mutex_t *mutex) +METHOD(condvar_t, wait_, void, + private_condvar_t *this, private_mutex_t *mutex) { if (mutex->recursive) { @@ -258,11 +250,8 @@ static void _wait(private_condvar_t *this, private_mutex_t *mutex) #define pthread_cond_timedwait pthread_cond_timedwait_monotonic #endif -/** - * Implementation of condvar_t.timed_wait_abs. - */ -static bool timed_wait_abs(private_condvar_t *this, private_mutex_t *mutex, - timeval_t time) +METHOD(condvar_t, timed_wait_abs, bool, + private_condvar_t *this, private_mutex_t *mutex, timeval_t time) { struct timespec ts; bool timed_out; @@ -287,11 +276,8 @@ static bool timed_wait_abs(private_condvar_t *this, private_mutex_t *mutex, return timed_out; } -/** - * Implementation of condvar_t.timed_wait. - */ -static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex, - u_int timeout) +METHOD(condvar_t, timed_wait, bool, + private_condvar_t *this, private_mutex_t *mutex, u_int timeout) { timeval_t tv; u_int s, ms; @@ -312,26 +298,20 @@ static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex, return timed_wait_abs(this, mutex, tv); } -/** - * Implementation of condvar_t.signal. - */ -static void _signal(private_condvar_t *this) +METHOD(condvar_t, signal_, void, + private_condvar_t *this) { pthread_cond_signal(&this->condvar); } -/** - * Implementation of condvar_t.broadcast. - */ -static void broadcast(private_condvar_t *this) +METHOD(condvar_t, broadcast, void, + private_condvar_t *this) { pthread_cond_broadcast(&this->condvar); } -/** - * Implementation of condvar_t.destroy - */ -static void condvar_destroy(private_condvar_t *this) +METHOD(condvar_t, condvar_destroy, void, + private_condvar_t *this) { pthread_cond_destroy(&this->condvar); free(this); @@ -347,14 +327,18 @@ condvar_t *condvar_create(condvar_type_t type) case CONDVAR_TYPE_DEFAULT: default: { - private_condvar_t *this = malloc_thing(private_condvar_t); - - this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))_wait; - this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait; - this->public.timed_wait_abs = (bool(*)(condvar_t*, mutex_t *mutex, timeval_t time))timed_wait_abs; - this->public.signal = (void(*)(condvar_t*))_signal; - this->public.broadcast = (void(*)(condvar_t*))broadcast; - this->public.destroy = (void(*)(condvar_t*))condvar_destroy; + private_condvar_t *this; + + INIT(this, + .public = { + .wait = (void*)_wait_, + .timed_wait = (void*)_timed_wait, + .timed_wait_abs = (void*)_timed_wait_abs, + .signal = _signal_, + .broadcast = _broadcast, + .destroy = _condvar_destroy, + } + ); #ifdef HAVE_PTHREAD_CONDATTR_INIT { diff --git a/src/libstrongswan/threading/rwlock.c b/src/libstrongswan/threading/rwlock.c index cec43f59c..15dc0b334 100644 --- a/src/libstrongswan/threading/rwlock.c +++ b/src/libstrongswan/threading/rwlock.c @@ -87,10 +87,8 @@ struct private_rwlock_t { #ifdef HAVE_PTHREAD_RWLOCK_INIT -/** - * Implementation of rwlock_t.read_lock - */ -static void read_lock(private_rwlock_t *this) +METHOD(rwlock_t, read_lock, void, + private_rwlock_t *this) { int err; @@ -103,10 +101,8 @@ static void read_lock(private_rwlock_t *this) profiler_end(&this->profile); } -/** - * Implementation of rwlock_t.write_lock - */ -static void write_lock(private_rwlock_t *this) +METHOD(rwlock_t, write_lock, void, + private_rwlock_t *this) { int err; @@ -119,18 +115,14 @@ static void write_lock(private_rwlock_t *this) profiler_end(&this->profile); } -/** - * Implementation of rwlock_t.try_write_lock - */ -static bool try_write_lock(private_rwlock_t *this) +METHOD(rwlock_t, try_write_lock, bool, + private_rwlock_t *this) { return pthread_rwlock_trywrlock(&this->rwlock) == 0; } -/** - * Implementation of rwlock_t.unlock - */ -static void rw_unlock(private_rwlock_t *this) +METHOD(rwlock_t, unlock, void, + private_rwlock_t *this) { int err; @@ -141,10 +133,8 @@ static void rw_unlock(private_rwlock_t *this) } } -/** - * Implementation of rwlock_t.destroy - */ -static void rw_destroy(private_rwlock_t *this) +METHOD(rwlock_t, destroy, void, + private_rwlock_t *this) { pthread_rwlock_destroy(&this->rwlock); profiler_cleanup(&this->profile); @@ -161,13 +151,17 @@ rwlock_t *rwlock_create(rwlock_type_t type) case RWLOCK_TYPE_DEFAULT: default: { - private_rwlock_t *this = malloc_thing(private_rwlock_t); - - this->public.read_lock = (void(*)(rwlock_t*))read_lock; - this->public.write_lock = (void(*)(rwlock_t*))write_lock; - this->public.try_write_lock = (bool(*)(rwlock_t*))try_write_lock; - this->public.unlock = (void(*)(rwlock_t*))rw_unlock; - this->public.destroy = (void(*)(rwlock_t*))rw_destroy; + private_rwlock_t *this; + + INIT(this, + .public = { + .read_lock = _read_lock, + .write_lock = _write_lock, + .try_write_lock = _try_write_lock, + .unlock = _unlock, + .destroy = _destroy, + } + ); pthread_rwlock_init(&this->rwlock, NULL); profiler_init(&this->profile); @@ -200,10 +194,8 @@ rwlock_t *rwlock_create(rwlock_type_t type) * checked or enforced so behave yourself to prevent deadlocks). */ -/** - * Implementation of rwlock_t.read_lock - */ -static void read_lock(private_rwlock_t *this) +METHOD(rwlock_t, read_lock, void, + private_rwlock_t *this) { profiler_start(&this->profile); this->mutex->lock(this->mutex); @@ -216,10 +208,8 @@ static void read_lock(private_rwlock_t *this) this->mutex->unlock(this->mutex); } -/** - * Implementation of rwlock_t.write_lock - */ -static void write_lock(private_rwlock_t *this) +METHOD(rwlock_t, write_lock, void, + private_rwlock_t *this) { profiler_start(&this->profile); this->mutex->lock(this->mutex); @@ -234,10 +224,8 @@ static void write_lock(private_rwlock_t *this) this->mutex->unlock(this->mutex); } -/** - * Implementation of rwlock_t.try_write_lock - */ -static bool try_write_lock(private_rwlock_t *this) +METHOD(rwlock_t, try_write_lock, bool, + private_rwlock_t *this) { bool res = FALSE; this->mutex->lock(this->mutex); @@ -250,10 +238,8 @@ static bool try_write_lock(private_rwlock_t *this) return res; } -/** - * Implementation of rwlock_t.unlock - */ -static void rw_unlock(private_rwlock_t *this) +METHOD(rwlock_t, unlock, void, + private_rwlock_t *this) { this->mutex->lock(this->mutex); if (this->writer == pthread_self()) @@ -279,10 +265,8 @@ static void rw_unlock(private_rwlock_t *this) this->mutex->unlock(this->mutex); } -/** - * Implementation of rwlock_t.destroy - */ -static void rw_destroy(private_rwlock_t *this) +METHOD(rwlock_t, destroy, void, + private_rwlock_t *this) { this->mutex->destroy(this->mutex); this->writers->destroy(this->writers); @@ -301,20 +285,20 @@ rwlock_t *rwlock_create(rwlock_type_t type) case RWLOCK_TYPE_DEFAULT: default: { - private_rwlock_t *this = malloc_thing(private_rwlock_t); - - this->public.read_lock = (void(*)(rwlock_t*))read_lock; - this->public.write_lock = (void(*)(rwlock_t*))write_lock; - this->public.try_write_lock = (bool(*)(rwlock_t*))try_write_lock; - this->public.unlock = (void(*)(rwlock_t*))rw_unlock; - this->public.destroy = (void(*)(rwlock_t*))rw_destroy; - - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); - this->writers = condvar_create(CONDVAR_TYPE_DEFAULT); - this->readers = condvar_create(CONDVAR_TYPE_DEFAULT); - this->waiting_writers = 0; - this->reader_count = 0; - this->writer = 0; + private_rwlock_t *this; + + INIT(this, + .public = { + .read_lock = _read_lock, + .write_lock = _write_lock, + .try_write_lock = _try_write_lock, + .unlock = _unlock, + .destroy = _destroy, + }, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .writers = condvar_create(CONDVAR_TYPE_DEFAULT), + .readers = condvar_create(CONDVAR_TYPE_DEFAULT), + ); profiler_init(&this->profile); diff --git a/src/libstrongswan/threading/thread.c b/src/libstrongswan/threading/thread.c index fcc0019d8..49a1b8430 100644 --- a/src/libstrongswan/threading/thread.c +++ b/src/libstrongswan/threading/thread.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Tobias Brunner + * Copyright (C) 2009-2012 Tobias Brunner * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,6 +18,19 @@ #include <signal.h> #include <semaphore.h> +#ifdef HAVE_GETTID +#include <sys/types.h> +#include <unistd.h> +#endif + +#ifdef HAVE_SYS_GETTID +#include <sys/syscall.h> +static inline pid_t gettid() +{ + return syscall(SYS_gettid); +} +#endif + #include <library.h> #include <debug.h> @@ -113,6 +126,7 @@ static mutex_t *id_mutex; */ static thread_value_t *current_thread; + #ifndef HAVE_PTHREAD_CANCEL /* if pthread_cancel is not available, we emulate it using a signal */ #define SIG_CANCEL (SIGRTMIN+7) @@ -146,10 +160,8 @@ static void thread_destroy(private_thread_t *this) free(this); } -/** - * Implementation of thread_t.cancel. - */ -static void cancel(private_thread_t *this) +METHOD(thread_t, cancel, void, + private_thread_t *this) { this->mutex->lock(this->mutex); if (pthread_equal(this->thread_id, pthread_self())) @@ -166,10 +178,8 @@ static void cancel(private_thread_t *this) this->mutex->unlock(this->mutex); } -/** - * Implementation of thread_t.kill. - */ -static void _kill(private_thread_t *this, int sig) +METHOD(thread_t, kill_, void, + private_thread_t *this, int sig) { this->mutex->lock(this->mutex); if (pthread_equal(this->thread_id, pthread_self())) @@ -187,10 +197,8 @@ static void _kill(private_thread_t *this, int sig) this->mutex->unlock(this->mutex); } -/** - * Implementation of thread_t.detach. - */ -static void detach(private_thread_t *this) +METHOD(thread_t, detach, void, + private_thread_t *this) { this->mutex->lock(this->mutex); pthread_detach(this->thread_id); @@ -198,10 +206,8 @@ static void detach(private_thread_t *this) thread_destroy(this); } -/** - * Implementation of thread_t.join. - */ -static void *join(private_thread_t *this) +METHOD(thread_t, join, void*, + private_thread_t *this) { pthread_t thread_id; void *val; @@ -241,22 +247,19 @@ static void *join(private_thread_t *this) */ static private_thread_t *thread_create_internal() { - private_thread_t *this = malloc_thing(private_thread_t); - - this->public.cancel = (void(*)(thread_t*))cancel; - this->public.kill = (void(*)(thread_t*,int))_kill; - this->public.detach = (void(*)(thread_t*))detach; - this->public.join = (void*(*)(thread_t*))join; - - this->id = 0; - this->thread_id = 0; - this->main = NULL; - this->arg = NULL; - this->cleanup_handlers = linked_list_create(); - this->mutex = mutex_create(MUTEX_TYPE_DEFAULT); + private_thread_t *this; + + INIT(this, + .public = { + .cancel = _cancel, + .kill = _kill_, + .detach = _detach, + .join = _join, + }, + .cleanup_handlers = linked_list_create(), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + ); sem_init(&this->created, FALSE, 0); - this->detached_or_joined = FALSE; - this->terminated = FALSE; return this; } @@ -288,6 +291,17 @@ static void *thread_main(private_thread_t *this) sem_wait(&this->created); current_thread->set(current_thread, this); pthread_cleanup_push((thread_cleanup_t)thread_cleanup, this); + + /* TODO: this is not 100% portable as pthread_t is an opaque type (i.e. + * could be of any size, or even a struct) */ +#ifdef HAVE_GETTID + DBG2(DBG_LIB, "created thread %.2d [%u]", + this->id, gettid()); +#else + DBG2(DBG_LIB, "created thread %.2d [%lx]", + this->id, (u_long)this->thread_id); +#endif + res = this->main(this->arg); pthread_cleanup_pop(TRUE); @@ -344,10 +358,12 @@ void thread_cleanup_push(thread_cleanup_t cleanup, void *arg) private_thread_t *this = (private_thread_t*)thread_current(); cleanup_handler_t *handler; + INIT(handler, + .cleanup = cleanup, + .arg = arg, + ); + this->mutex->lock(this->mutex); - handler = malloc_thing(cleanup_handler_t); - handler->cleanup = cleanup; - handler->arg = arg; this->cleanup_handlers->insert_last(this->cleanup_handlers, handler); this->mutex->unlock(this->mutex); } @@ -422,12 +438,20 @@ void thread_exit(void *val) } /** + * A dummy thread value that reserved pthread_key_t value "0". A buggy PKCS#11 + * library mangles this key, without owning it, so we allocate it for them. + */ +static thread_value_t *dummy1; + +/** * Described in header. */ void threads_init() { private_thread_t *main_thread = thread_create_internal(); + dummy1 = thread_value_create(NULL); + main_thread->id = 0; main_thread->thread_id = pthread_self(); current_thread = thread_value_create(NULL); @@ -451,6 +475,8 @@ void threads_deinit() { private_thread_t *main_thread = (private_thread_t*)thread_current(); + dummy1->destroy(dummy1); + main_thread->mutex->lock(main_thread->mutex); thread_destroy(main_thread); current_thread->destroy(current_thread); diff --git a/src/libstrongswan/threading/thread_value.c b/src/libstrongswan/threading/thread_value.c index 8f2a8846c..3fa70acb2 100644 --- a/src/libstrongswan/threading/thread_value.c +++ b/src/libstrongswan/threading/thread_value.c @@ -35,27 +35,20 @@ struct private_thread_value_t { }; - -/** - * Implementation of thread_value_t.set. - */ -static void set(private_thread_value_t *this, void *val) +METHOD(thread_value_t, set, void, + private_thread_value_t *this, void *val) { pthread_setspecific(this->key, val); } -/** - * Implementation of thread_value_t.get. - */ -static void *get(private_thread_value_t *this) +METHOD(thread_value_t, get, void*, + private_thread_value_t *this) { return pthread_getspecific(this->key); } -/** - * Implementation of thread_value_t.destroy. - */ -static void destroy(private_thread_value_t *this) +METHOD(thread_value_t, destroy, void, + private_thread_value_t *this) { pthread_key_delete(this->key); free(this); @@ -67,10 +60,15 @@ static void destroy(private_thread_value_t *this) */ thread_value_t *thread_value_create(thread_cleanup_t destructor) { - private_thread_value_t *this = malloc_thing(private_thread_value_t); - this->public.set = (void(*)(thread_value_t*,void*))set; - this->public.get = (void*(*)(thread_value_t*))get; - this->public.destroy = (void(*)(thread_value_t*))destroy; + private_thread_value_t *this; + + INIT(this, + .public = { + .set = _set, + .get = _get, + .destroy = _destroy, + }, + ); pthread_key_create(&this->key, destructor); return &this->public; |