From 278644952ae5b97b8b27ce20a80c20494b4f081a Mon Sep 17 00:00:00 2001 From: Lammert Bies Date: Tue, 20 Dec 2016 07:25:54 +0100 Subject: [PATCH] Made httplib_pthread_cond_signal global --- Makefile | 5 +- doc/api/httplib_pthread_cond_signal.md | 27 +++++++++++ include/libhttp.h | 1 + src/httplib_consume_socket.c | 3 +- src/httplib_event_queue.c | 10 ++-- src/httplib_produce_socket.c | 2 +- src/httplib_pthread.h | 1 - ...signal.c => httplib_pthread_cond_signal.c} | 48 +++++++++++++------ src/win32_pthread_cond_broadcast.c | 8 ++-- 9 files changed, 79 insertions(+), 26 deletions(-) create mode 100644 doc/api/httplib_pthread_cond_signal.md rename src/{win32_pthread_cond_signal.c => httplib_pthread_cond_signal.c} (58%) diff --git a/Makefile b/Makefile index fac14b7e..89f65a84 100644 --- a/Makefile +++ b/Makefile @@ -375,7 +375,7 @@ OBJLIST = \ ${OBJDIR}win32_pthread_cond_broadcast${OBJEXT} \ ${OBJDIR}win32_pthread_cond_destroy${OBJEXT} \ ${OBJDIR}win32_pthread_cond_init${OBJEXT} \ - ${OBJDIR}win32_pthread_cond_signal${OBJEXT} \ + ${OBJDIR}httplib_pthread_cond_signal${OBJEXT} \ ${OBJDIR}httplib_pthread_cond_timedwait${OBJEXT} \ ${OBJDIR}httplib_pthread_cond_wait${OBJEXT} \ ${OBJDIR}httplib_pthread_getspecific${OBJEXT} \ @@ -1406,8 +1406,7 @@ ${OBJDIR}win32_pthread_cond_init${OBJEXT} : ${SRCDIR}win32_pthread_cond_init. ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h -${OBJDIR}win32_pthread_cond_signal${OBJEXT} : ${SRCDIR}win32_pthread_cond_signal.c \ - ${SRCDIR}httplib_pthread.h \ +${OBJDIR}httplib_pthread_cond_signal${OBJEXT} : ${SRCDIR}httplib_pthread_cond_signal.c \ ${SRCDIR}httplib_main.h \ ${INCDIR}libhttp.h diff --git a/doc/api/httplib_pthread_cond_signal.md b/doc/api/httplib_pthread_cond_signal.md new file mode 100644 index 00000000..abac3ade --- /dev/null +++ b/doc/api/httplib_pthread_cond_signal.md @@ -0,0 +1,27 @@ +# LibHTTP API Reference + +### `httplib_pthread_cond_signal( cv );` + +### Parameters + +| Parameter | Type | Description | +| :--- | :--- | :--- | +|**`cv`**|`pthread_cond_t *`|The condition which a thread is waiting on| + +### Return Value + +| Type | Description | +| :--- | :--- | +|`int`|Integer value with a success or error code of the function call| + +### Description + +The platform independent function `httplib_pthread_cond_signal()` unlocks one thread waiting on a specific condition. The function returns **0** when successful and an error code otherwise. On systems which support it, the functionality is implemented as a direct call to `pthread_cond_signal()`. Otherwise an OS dependent alternative implementation is used to emulate the same behavior. + +### See Also + +* [`httplib_pthread_cond_broadcast();`](httplib_pthread_cond_broadcast.md) +* [`httplib_pthread_cond_destroy();`](httplib_pthread_cond_destroy.md) +* [`httplib_pthread_cond_init();`](httplib_pthread_cond_init.md) +* [`httplib_pthread_cond_timedwait();`](httplib_pthread_cond_timedwait.md) +* [`httplib_pthread_cond_wait();`](httplib_pthread_cond_wait.md) diff --git a/include/libhttp.h b/include/libhttp.h index d62cdbf2..a7dc55fd 100644 --- a/include/libhttp.h +++ b/include/libhttp.h @@ -985,6 +985,7 @@ LIBHTTP_API int httplib_kill( pid_t pid, int sig_num ); LIBHTTP_API int httplib_mkdir( const char *path, int mode ); LIBHTTP_API DIR * httplib_opendir( const char *name ); LIBHTTP_API int httplib_poll( struct pollfd *pfd, unsigned int nfds, int timeout ); +LIBHTTP_API int httplib_pthread_cond_signal( pthread_cond_t *cv ); LIBHTTP_API int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec *abstime ); LIBHTTP_API int httplib_pthread_cond_wait( pthread_cond_t *cv, pthread_mutex_t *mutex ); LIBHTTP_API void * httplib_pthread_getspecific( pthread_key_t key ); diff --git a/src/httplib_consume_socket.c b/src/httplib_consume_socket.c index ac938714..1df313cd 100644 --- a/src/httplib_consume_socket.c +++ b/src/httplib_consume_socket.c @@ -72,12 +72,13 @@ int XX_httplib_consume_socket( struct httplib_context *ctx, struct socket *sp, i /* Wrap pointers if needed */ while (ctx->sq_tail > QUEUE_SIZE(ctx)) { + ctx->sq_tail -= QUEUE_SIZE(ctx); ctx->sq_head -= QUEUE_SIZE(ctx); } } - pthread_cond_signal(&ctx->sq_empty); + httplib_pthread_cond_signal( & ctx->sq_empty ); httplib_pthread_mutex_unlock( & ctx->thread_mutex ); return !ctx->stop_flag; diff --git a/src/httplib_event_queue.c b/src/httplib_event_queue.c index af8a1e36..24c51ebd 100644 --- a/src/httplib_event_queue.c +++ b/src/httplib_event_queue.c @@ -131,10 +131,14 @@ int event_wait(void *eventhdl) { int event_signal(void *eventhdl) { - struct posix_event *ev = (struct posix_event *)eventhdl; - httplib_pthread_mutex_lock( & ev->mutex ); - pthread_cond_signal(&(ev->cond)); + struct posix_event *ev; + + ev = eventhdl; + + httplib_pthread_mutex_lock( & ev->mutex ); + httplib_pthread_cond_signal( & ev->cond ); httplib_pthread_mutex_unlock( & ev->mutex ); + return 1; } /* event_signal */ diff --git a/src/httplib_produce_socket.c b/src/httplib_produce_socket.c index a0feaf52..56a5074d 100644 --- a/src/httplib_produce_socket.c +++ b/src/httplib_produce_socket.c @@ -79,7 +79,7 @@ void XX_httplib_produce_socket(struct httplib_context *ctx, const struct socket ctx->sq_head++; } - pthread_cond_signal(&ctx->sq_full); + httplib_pthread_cond_signal( & ctx->sq_full ); httplib_pthread_mutex_unlock( & ctx->thread_mutex ); #undef QUEUE_SIZE diff --git a/src/httplib_pthread.h b/src/httplib_pthread.h index b723b08e..4c346df6 100644 --- a/src/httplib_pthread.h +++ b/src/httplib_pthread.h @@ -33,6 +33,5 @@ extern int XX_httplib_thread_idx_max; int pthread_cond_broadcast( pthread_cond_t *cv ); int pthread_cond_destroy( pthread_cond_t *cv ); int pthread_cond_init( pthread_cond_t *cv, const pthread_condattr_t *attr ); -int pthread_cond_signal( pthread_cond_t *cv ); #endif /* _WIN32 */ diff --git a/src/win32_pthread_cond_signal.c b/src/httplib_pthread_cond_signal.c similarity index 58% rename from src/win32_pthread_cond_signal.c rename to src/httplib_pthread_cond_signal.c index b61167de..c572793b 100644 --- a/src/win32_pthread_cond_signal.c +++ b/src/httplib_pthread_cond_signal.c @@ -22,31 +22,51 @@ * THE SOFTWARE. * * ============ - * Release: 1.8 + * Release: 2.0 */ #include "httplib_main.h" -#include "httplib_pthread.h" + +/* + * int httplib_pthread_cond_signal( pthread_cond_t *cv ); + * + * The platform independent function httplib_pthread_cond_signal() unlocks a + * blocking condition for one thread. Of the function is successful, the value + * 0 will be returned. Otherwise the returned value is an error code. + * + * On systems which support it, the function is a wrapper around the function + * pthread_cond_signal(). In other environments own code is used which emulates + * the same behaviour. + */ + +int httplib_pthread_cond_signal( pthread_cond_t *cv ) { #if defined(_WIN32) -int pthread_cond_signal( pthread_cond_t *cv ) { + HANDLE wkup; + bool ok; - HANDLE wkup = NULL; - BOOL ok = FALSE; + wkup = NULL; + ok = false; - EnterCriticalSection(&cv->threadIdSec); - if (cv->waiting_thread) { - wkup = cv->waiting_thread->pthread_cond_helper_mutex; + EnterCriticalSection( & cv->threadIdSec ); + + if ( cv->waiting_thread ) { + + wkup = cv->waiting_thread->pthread_cond_helper_mutex; cv->waiting_thread = cv->waiting_thread->next_waiting_thread; - ok = SetEvent(wkup); - assert(ok); + ok = SetEvent( wkup ); } - LeaveCriticalSection(&cv->threadIdSec); - return ok ? 0 : 1; + LeaveCriticalSection( & cv->threadIdSec ); -} /* pthread_cond_signal */ + return ( ok ) ? 0 : 1; -#endif /* _WIN32 */ +#else /* _WIN32 */ + + return pthread_cond_signal( cv ); + +#endif + +} /* httplib_pthread_cond_signal */ diff --git a/src/win32_pthread_cond_broadcast.c b/src/win32_pthread_cond_broadcast.c index 3690461a..1ee0eaa8 100644 --- a/src/win32_pthread_cond_broadcast.c +++ b/src/win32_pthread_cond_broadcast.c @@ -32,9 +32,11 @@ int pthread_cond_broadcast( pthread_cond_t *cv ) { - EnterCriticalSection(&cv->threadIdSec); - while (cv->waiting_thread) pthread_cond_signal(cv); - LeaveCriticalSection(&cv->threadIdSec); + EnterCriticalSection( & cv->threadIdSec ); + + while ( cv->waiting_thread ) httplib_pthread_cond_signal( cv ); + + LeaveCriticalSection( & cv->threadIdSec ); return 0;