semaphore: Support cancellation in wait functions of semaphore fallback

Semaphore wait functions should be a thread cancellation point, but did
not properly release the mutex in the fallback implementation.
This commit is contained in:
Martin Willi
2013-10-23 16:08:40 +02:00
parent 47c76c1b05
commit b08292a520
+6 -4
View File
@@ -26,6 +26,7 @@
#ifdef HAVE_SEM_TIMEDWAIT #ifdef HAVE_SEM_TIMEDWAIT
#include <semaphore.h> #include <semaphore.h>
#else /* !HAVE_SEM_TIMEDWAIT */ #else /* !HAVE_SEM_TIMEDWAIT */
#include <threading/thread.h>
#include <threading/condvar.h> #include <threading/condvar.h>
#endif /* HAVE_SEM_TIMEDWAIT */ #endif /* HAVE_SEM_TIMEDWAIT */
@@ -73,12 +74,13 @@ METHOD(semaphore_t, wait_, void,
sem_wait(&this->sem); sem_wait(&this->sem);
#else /* !HAVE_SEM_TIMEDWAIT */ #else /* !HAVE_SEM_TIMEDWAIT */
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
thread_cleanup_push((void*)this->mutex->unlock, this->mutex);
while (this->count == 0) while (this->count == 0)
{ {
this->cond->wait(this->cond, this->mutex); this->cond->wait(this->cond, this->mutex);
} }
this->count--; this->count--;
this->mutex->unlock(this->mutex); thread_cleanup_pop(TRUE);
#endif /* HAVE_SEM_TIMEDWAIT */ #endif /* HAVE_SEM_TIMEDWAIT */
} }
@@ -96,16 +98,17 @@ METHOD(semaphore_t, timed_wait_abs, bool,
return sem_timedwait(&this->sem, &ts) == -1; return sem_timedwait(&this->sem, &ts) == -1;
#else /* !HAVE_SEM_TIMEDWAIT */ #else /* !HAVE_SEM_TIMEDWAIT */
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
thread_cleanup_push((void*)this->mutex->unlock, this->mutex);
while (this->count == 0) while (this->count == 0)
{ {
if (this->cond->timed_wait_abs(this->cond, this->mutex, tv)) if (this->cond->timed_wait_abs(this->cond, this->mutex, tv))
{ {
this->mutex->unlock(this->mutex); thread_cleanup_pop(TRUE);
return TRUE; return TRUE;
} }
} }
this->count--; this->count--;
this->mutex->unlock(this->mutex); thread_cleanup_pop(TRUE);
return FALSE; return FALSE;
#endif /* HAVE_SEM_TIMEDWAIT */ #endif /* HAVE_SEM_TIMEDWAIT */
} }
@@ -176,4 +179,3 @@ semaphore_t *semaphore_create(u_int value)
return &this->public; return &this->public;
} }