From 6ba98a9f9f48e13738d9736cba9c45b5e94f42f2 Mon Sep 17 00:00:00 2001 From: Brian Cully Date: Mon, 14 Apr 2008 21:52:55 -0400 Subject: Initial import --- server/thread.c | 216 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 server/thread.c (limited to 'server/thread.c') diff --git a/server/thread.c b/server/thread.c new file mode 100644 index 0000000..95737d6 --- /dev/null +++ b/server/thread.c @@ -0,0 +1,216 @@ +#include "conf.h" +#include "log.h" +#include "thread.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +RCSID("$Id: thread.c,v 1.6 2000/03/21 19:18:24 shmit Exp $"); + +int +thread_new(thread_t *thread, void *(*thread_func)(void *), void *arg) +{ + int rc; + + thread->thread_func = thread_func; + rc = pthread_create(&thread->id, NULL, thread_func, arg); + if (rc != 0) { + log_err("Couldn't create thread: %s.\n", strerror(rc)); + return -1; + } + return 0; +} + +void +thread_kill(thread_t *thread) +{ +} + +int +thread_reload(thread_t *thread) +{ + return 0; +} + +int +mutex_new(mutex_t *lock) +{ + return pthread_mutex_init(lock, NULL); +} + +int +mutex_delete(mutex_t *lock) +{ + return pthread_mutex_destroy(lock); +} + +int +mutex_lock(mutex_t *lock) +{ + return pthread_mutex_lock(lock); +} + +int +mutex_unlock(mutex_t *lock) +{ + return pthread_mutex_unlock(lock); +} + +int +rw_mutex_new(rw_mutex_t *lock) +{ + int rc; + + rc = mutex_new(&lock->lock); + if (rc) + return rc; + rc = pthread_cond_init(&lock->read_sig, NULL); + if (rc) { + mutex_delete(&lock->lock); + return rc; + } + rc = pthread_cond_init(&lock->write_sig, NULL); + if (rc) { + mutex_delete(&lock->lock); + pthread_cond_destroy(&lock->read_sig); + return rc; + } + lock->state = 0; + lock->blocked_writers = 0; + + return 0; +} + +int +rw_mutex_read_lock(rw_mutex_t *lock) +{ + int rc; + + if (lock == NULL) + return EINVAL; + + rc = mutex_lock(&lock->lock); + if (rc) + return rc; + + /* Make sure the writers go before the readers. */ + while (lock->blocked_writers || lock->state < 0) { + rc = pthread_cond_wait(&lock->read_sig, &lock->lock); + if (rc) { + mutex_unlock(&lock->lock); + return rc; + } + } + lock->state++; + mutex_unlock(&lock->lock); + + return rc; +} + +int +rw_mutex_write_lock(rw_mutex_t *lock) +{ + int rc; + + if (lock == NULL) + return EINVAL; + + rc = mutex_lock(&lock->lock); + if (rc) + return rc; + + /* Wait for no readers on the lock. */ + while (lock->state != 0) { + lock->blocked_writers++; + rc = pthread_cond_wait(&lock->write_sig, &lock->lock); + lock->blocked_writers--; + if (rc) { + mutex_unlock(&lock->lock); + return rc; + } + } + lock->state = -1; + + mutex_unlock(&lock->lock); + return rc; +} + +int +rw_mutex_unlock(rw_mutex_t *lock) +{ + int rc; + + if (lock == NULL) + return EINVAL; + + rc = mutex_lock(&lock->lock); + if (rc) + return rc; + + if (lock->state > 0) { + /* We have an open read lock. */ + if (--lock->state == 0 && lock->blocked_writers) + rc = pthread_cond_signal(&lock->write_sig); + } else if (lock->state < 0) { + /* We have an open writer lock. */ + lock->state = 0; + if (lock->blocked_writers) + rc = pthread_cond_signal(&lock->write_sig); + else + rc = pthread_cond_broadcast(&lock->read_sig); + } else + rc = EINVAL; + + mutex_unlock(&lock->lock); + return rc; +} + +int +cond_new(cond_t *cond) +{ + int rc; + + if (cond == NULL) + return EINVAL; + + rc = pthread_cond_init(&cond->id, NULL); + if (rc) + return rc; + + rc = mutex_new(&cond->lock); + if (rc) + pthread_cond_destroy(&cond->id); + + return rc; +} + +int +cond_signal(cond_t *cond) +{ + return pthread_cond_signal(&cond->id); +} + +int +cond_wait(cond_t *cond) +{ + return pthread_cond_wait(&cond->id, &cond->lock); +} + +int +cond_timedwait(cond_t *cond, const struct timespec *abstime) +{ + return pthread_cond_timedwait(&cond->id, &cond->lock, abstime); +} + +int +cond_destroy(cond_t *cond) +{ + return pthread_cond_destroy(&cond->id); +} -- cgit v1.2.3