1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-09 03:22:45 +03:00

Made httplib_pthread_cond_timedwait global

This commit is contained in:
Lammert Bies
2016-12-19 19:17:46 +01:00
parent 368a077775
commit 554f838aa0
5 changed files with 154 additions and 93 deletions

View File

@@ -376,7 +376,7 @@ OBJLIST = \
${OBJDIR}win32_pthread_cond_destroy${OBJEXT} \
${OBJDIR}win32_pthread_cond_init${OBJEXT} \
${OBJDIR}win32_pthread_cond_signal${OBJEXT} \
${OBJDIR}win32_pthread_cond_timedwait${OBJEXT} \
${OBJDIR}httplib_pthread_cond_timedwait${OBJEXT} \
${OBJDIR}httplib_pthread_cond_wait${OBJEXT} \
${OBJDIR}httplib_pthread_getspecific${OBJEXT} \
${OBJDIR}httplib_pthread_key_create${OBJEXT} \
@@ -1411,8 +1411,7 @@ ${OBJDIR}win32_pthread_cond_signal${OBJEXT} : ${SRCDIR}win32_pthread_cond_sig
${SRCDIR}httplib_main.h \
${INCDIR}libhttp.h
${OBJDIR}win32_pthread_cond_timedwait${OBJEXT} : ${SRCDIR}win32_pthread_cond_timedwait.c \
${SRCDIR}httplib_pthread.h \
${OBJDIR}httplib_pthread_cond_timedwait${OBJEXT} : ${SRCDIR}httplib_pthread_cond_timedwait.c \
${SRCDIR}httplib_main.h \
${INCDIR}libhttp.h

View File

@@ -0,0 +1,29 @@
# LibHTTP API Reference
### `httplib_pthread_cond_timedwait( cv, mutex, abstime );`
### Parameters
| Parameter | Type | Description |
| :--- | :--- | :--- |
|**`cv`**|`pthread_cond_t`|The condition to wait for|
|**`mutex`**|`pthread_mutex_t *`|The mutex to release when the condition is met|
|**`abstime`**|`const struct timespec *`|structure containing the desired timeout time|
### 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_timedwait()` is used to wait for a specific condition to be met. After the condition is met, the specified mutex is unlocked. If the function succeeds, the value **0** is returned, otherwise the return value is an error code. A timeout value is specified after which the function will return, even if the condition is not met. In the later case an error code indicating the timeout is returned. On systems which support it, the functionality is implemented as a direct call to `pthread_cond_timedwait()`. Otherwise an OS dependent alternative function is called.
### 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_signal();`](httplib_pthread_cond_signal.md)
* [`httplib_pthread_cond_wait();`](httplib_pthread_cond_wait.md)

View File

@@ -34,6 +34,5 @@ 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 );
int pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec *abstime );
#endif /* _WIN32 */

View File

@@ -0,0 +1,123 @@
/*
* Copyright (c) 2016 Lammert Bies
* Copyright (c) 2013-2016 the Civetweb developers
* Copyright (c) 2004-2013 Sergey Lyubka
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* ============
* Release: 2.0
*/
#include "httplib_main.h"
/*
* int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex *mutex, const struct timespec *abstime );
*
* The platform independent function httplib_pthread_cond_timedwait() is used
* to wait until a specified condition is met. If that happens the specified
* mutex is released. The function stops after a timeout which is provided as a
* third parameter in the function call.
*
* On systems which support it, the call is implemented as a wrapper around the
* pthread_cond_timedwait() function. On other platforms the functionality is
* implemented with own code.
*/
int httplib_pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec *abstime ) {
#if defined(_WIN32)
struct httplib_workerTLS **ptls;
struct httplib_workerTLS *tls;
bool ok;
struct timespec tsnow;
int64_t nsnow;
int64_t nswaitabs;
int64_t nswaitrel;
DWORD mswaitrel;
tls = pthread_getspecific( XX_httplib_sTlsKey );
/* Add this thread to cv's waiting list */
EnterCriticalSection( & cv->threadIdSec );
ptls = & cv->waiting_thread;
while ( *ptls != NULL ) ptls = & (*ptls)->next_waiting_thread;
tls->next_waiting_thread = NULL;
*ptls = tls;
LeaveCriticalSection( & cv->threadIdSec );
if ( abstime ) {
clock_gettime( CLOCK_REALTIME, & tsnow );
nsnow = (((int64_t)tsnow.tv_sec) * 1000000000) + tsnow.tv_nsec;
nswaitabs = (((int64_t)abstime->tv_sec) * 1000000000) + abstime->tv_nsec;
nswaitrel = nswaitabs - nsnow;
if ( nswaitrel < 0 ) nswaitrel = 0;
mswaitrel = (DWORD)(nswaitrel / 1000000);
}
else mswaitrel = INFINITE;
pthread_mutex_unlock( mutex );
ok = ( WaitForSingleObject( tls->pthread_cond_helper_mutex, mswaitrel ) == WAIT_OBJECT_0 );
if ( ! ok ) {
ok = true;
EnterCriticalSection( & cv->threadIdSec );
ptls = & cv->waiting_thread;
while ( *ptls != NULL ) {
ptls = & (*ptls)->next_waiting_thread;
if ( *ptls == tls ) {
*ptls = tls->next_waiting_thread;
ok = false;
break;
}
}
LeaveCriticalSection( & cv->threadIdSec );
if ( ok ) WaitForSingleObject( tls->pthread_cond_helper_mutex, INFINITE );
}
/* This thread has been removed from cv's waiting list */
pthread_mutex_lock( mutex );
return ok ? 0 : -1;
#else /* _WIN32 */
return pthread_cond_timedwait( cv, mutex, abstime );
#endif /* _WIN32 */
} /* httplib_pthread_cond_timedwait */

View File

@@ -1,89 +0,0 @@
/*
* Copyright (c) 2016 Lammert Bies
* Copyright (c) 2013-2016 the Civetweb developers
* Copyright (c) 2004-2013 Sergey Lyubka
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* ============
* Release: 1.8
*/
#include "httplib_main.h"
#include "httplib_pthread.h"
#if defined(_WIN32)
int pthread_cond_timedwait( pthread_cond_t *cv, pthread_mutex_t *mutex, const struct timespec *abstime ) {
struct httplib_workerTLS **ptls;
struct httplib_workerTLS *tls = (struct httplib_workerTLS *)pthread_getspecific(XX_httplib_sTlsKey);
int ok;
struct timespec tsnow;
int64_t nsnow;
int64_t nswaitabs;
int64_t nswaitrel;
DWORD mswaitrel;
EnterCriticalSection(&cv->threadIdSec);
/* Add this thread to cv's waiting list */
ptls = &cv->waiting_thread;
for (; *ptls != NULL; ptls = &(*ptls)->next_waiting_thread)
;
tls->next_waiting_thread = NULL;
*ptls = tls;
LeaveCriticalSection(&cv->threadIdSec);
if (abstime) {
clock_gettime(CLOCK_REALTIME, &tsnow);
nsnow = (((int64_t)tsnow.tv_sec) * 1000000000) + tsnow.tv_nsec;
nswaitabs =
(((int64_t)abstime->tv_sec) * 1000000000) + abstime->tv_nsec;
nswaitrel = nswaitabs - nsnow;
if (nswaitrel < 0) {
nswaitrel = 0;
}
mswaitrel = (DWORD)(nswaitrel / 1000000);
} else mswaitrel = INFINITE;
pthread_mutex_unlock(mutex);
ok = (WAIT_OBJECT_0
== WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel));
if (!ok) {
ok = 1;
EnterCriticalSection(&cv->threadIdSec);
ptls = &cv->waiting_thread;
for (; *ptls != NULL; ptls = &(*ptls)->next_waiting_thread) {
if (*ptls == tls) {
*ptls = tls->next_waiting_thread;
ok = 0;
break;
}
}
LeaveCriticalSection(&cv->threadIdSec);
if (ok) WaitForSingleObject(tls->pthread_cond_helper_mutex, INFINITE);
}
/* This thread has been removed from cv's waiting list */
pthread_mutex_lock(mutex);
return ok ? 0 : -1;
} /* pthread_cond_timedwait */
#endif /* _WIN32 */