summaryrefslogtreecommitdiff
path: root/src/libstrongswan/threading
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/threading')
-rw-r--r--src/libstrongswan/threading/mutex.c128
-rw-r--r--src/libstrongswan/threading/rwlock.c106
-rw-r--r--src/libstrongswan/threading/thread.c96
-rw-r--r--src/libstrongswan/threading/thread_value.c32
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;