semaphore: Support cancellation in wait functions of semaphore fallback
authorMartin Willi <martin@revosec.ch>
Wed, 23 Oct 2013 14:05:40 +0000 (16:05 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 23 Oct 2013 14:08:40 +0000 (16:08 +0200)
Semaphore wait functions should be a thread cancellation point, but did
not properly release the mutex in the fallback implementation.

src/libstrongswan/threading/semaphore.c

index b785ff9..d90588b 100644 (file)
@@ -26,6 +26,7 @@
 #ifdef HAVE_SEM_TIMEDWAIT
 #include <semaphore.h>
 #else /* !HAVE_SEM_TIMEDWAIT */
+#include <threading/thread.h>
 #include <threading/condvar.h>
 #endif /* HAVE_SEM_TIMEDWAIT */
 
@@ -73,12 +74,13 @@ METHOD(semaphore_t, wait_, void,
        sem_wait(&this->sem);
 #else /* !HAVE_SEM_TIMEDWAIT */
        this->mutex->lock(this->mutex);
+       thread_cleanup_push((void*)this->mutex->unlock, this->mutex);
        while (this->count == 0)
        {
                this->cond->wait(this->cond, this->mutex);
        }
        this->count--;
-       this->mutex->unlock(this->mutex);
+       thread_cleanup_pop(TRUE);
 #endif /* HAVE_SEM_TIMEDWAIT */
 }
 
@@ -96,16 +98,17 @@ METHOD(semaphore_t, timed_wait_abs, bool,
        return sem_timedwait(&this->sem, &ts) == -1;
 #else /* !HAVE_SEM_TIMEDWAIT */
        this->mutex->lock(this->mutex);
+       thread_cleanup_push((void*)this->mutex->unlock, this->mutex);
        while (this->count == 0)
        {
                if (this->cond->timed_wait_abs(this->cond, this->mutex, tv))
                {
-                       this->mutex->unlock(this->mutex);
+                       thread_cleanup_pop(TRUE);
                        return TRUE;
                }
        }
        this->count--;
-       this->mutex->unlock(this->mutex);
+       thread_cleanup_pop(TRUE);
        return FALSE;
 #endif /* HAVE_SEM_TIMEDWAIT */
 }
@@ -176,4 +179,3 @@ semaphore_t *semaphore_create(u_int value)
 
        return &this->public;
 }
-