X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Funix%2Fsilcunixthread.c;h=7f52de901daca7baafd9d1c1bca4aaf949e52ad3;hb=9905799a86c606304fd7df2cd401de1740a272a1;hp=80e1a8e62f30164fc1fa05a37f79b0e243ce5642;hpb=c27a4ecc3e616e8a5ee09b8ca888ed6ff3e501f7;p=silc.git diff --git a/lib/silcutil/unix/silcunixthread.c b/lib/silcutil/unix/silcunixthread.c index 80e1a8e6..7f52de90 100644 --- a/lib/silcutil/unix/silcunixthread.c +++ b/lib/silcutil/unix/silcunixthread.c @@ -4,12 +4,12 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2005 Pekka Riikonen + Copyright (C) 2001 - 2006 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -18,7 +18,9 @@ */ /* $Id$ */ -#include "silcincludes.h" +#include "silc.h" + +/**************************** SILC Thread API *******************************/ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, SilcBool waitable) @@ -39,14 +41,14 @@ SilcThread silc_thread_create(SilcThreadStart start_func, void *context, } if (pthread_attr_setdetachstate(&attr, - waitable ? PTHREAD_CREATE_JOINABLE : + waitable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED)) { SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); pthread_attr_destroy(&attr); return NULL; } - ret = pthread_create(&thread, &attr, (void * (*)(void *))start_func, + ret = pthread_create(&thread, &attr, (void * (*)(void *))start_func, context); if (ret) { SILC_LOG_ERROR(("Thread error: %s", strerror(errno))); @@ -94,3 +96,139 @@ SilcBool silc_thread_wait(SilcThread thread, void **exit_value) return FALSE; #endif } + + +/***************************** SILC Mutex API *******************************/ + +/* SILC Mutex structure */ +struct SilcMutexStruct { +#ifdef SILC_THREADS + pthread_mutex_t mutex; +#endif /* SILC_THREADS */ + unsigned int locked : 1; +}; + +SilcBool silc_mutex_alloc(SilcMutex *mutex) +{ +#ifdef SILC_THREADS + *mutex = silc_calloc(1, sizeof(**mutex)); + if (*mutex == NULL) + return FALSE; + pthread_mutex_init(&(*mutex)->mutex, NULL); + (*mutex)->locked = FALSE; + return TRUE; +#else + return FALSE; +#endif /* SILC_THREADS */ +} + +void silc_mutex_free(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) { + pthread_mutex_destroy(&mutex->mutex); + silc_free(mutex); + } +#endif /* SILC_THREADS */ +} + +void silc_mutex_lock(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) { + if (pthread_mutex_lock(&mutex->mutex)) + SILC_ASSERT(FALSE); + mutex->locked = TRUE; + } +#endif /* SILC_THREADS */ +} + +void silc_mutex_unlock(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) { + if (pthread_mutex_unlock(&mutex->mutex)) + SILC_ASSERT(FALSE); + mutex->locked = FALSE; + } +#endif /* SILC_THREADS */ +} + +void silc_mutex_assert_locked(SilcMutex mutex) +{ +#ifdef SILC_THREADS + if (mutex) + SILC_ASSERT(mutex->locked); +#endif /* SILC_THREADS */ +} + + +/****************************** SILC Cond API *******************************/ + +/* SILC Conditional Variable context */ +struct SilcCondStruct { +#ifdef SILC_THREADS + pthread_cond_t cond; +#else + void *tmp; +#endif /* SILC_THREADS*/ +}; + +SilcBool silc_cond_alloc(SilcCond *cond) +{ +#ifdef SILC_THREADS + *cond = silc_calloc(1, sizeof(**cond)); + if (*cond == NULL) + return FALSE; + pthread_cond_init(&(*cond)->cond, NULL); + return TRUE; +#else + return FALSE; +#endif /* SILC_THREADS*/ +} + +void silc_cond_free(SilcCond cond) +{ +#ifdef SILC_THREADS + pthread_cond_destroy(&cond->cond); + silc_free(cond); +#endif /* SILC_THREADS*/ +} + +void silc_cond_signal(SilcCond cond) +{ +#ifdef SILC_THREADS + pthread_cond_signal(&cond->cond); +#endif /* SILC_THREADS*/ +} + +void silc_cond_broadcast(SilcCond cond) +{ +#ifdef SILC_THREADS + pthread_cond_broadcast(&cond->cond); +#endif /* SILC_THREADS*/ +} + +void silc_cond_wait(SilcCond cond, SilcMutex mutex) +{ +#ifdef SILC_THREADS + pthread_cond_wait(&cond->cond, &mutex->mutex); +#endif /* SILC_THREADS*/ +} + +SilcBool silc_cond_timedwait(SilcCond cond, SilcMutex mutex, + int timeout) +{ +#ifdef SILC_THREADS + struct timespec t; + if (timeout) { + t.tv_sec = timeout / 1000; + t.tv_nsec = (timeout % 1000) * 1000; + return pthread_cond_timedwait(&cond->cond, &mutex->mutex, &t) == 0; + } + + return pthread_cond_wait(&cond->cond, &mutex->mutex) == 0; +#else + return FALSE; +#endif /* SILC_THREADS*/ +}