summaryrefslogtreecommitdiff
path: root/src/libstrongswan/threading
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2013-11-01 13:32:07 +0100
committerYves-Alexis Perez <corsac@debian.org>2013-11-01 13:32:07 +0100
commit5313d2d78ca150515f7f5eb39801c100690b6b29 (patch)
treec78e420367283bb1b16f14210b12687cdfbd26eb /src/libstrongswan/threading
parent6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349 (diff)
downloadvyos-strongswan-5313d2d78ca150515f7f5eb39801c100690b6b29.tar.gz
vyos-strongswan-5313d2d78ca150515f7f5eb39801c100690b6b29.zip
Imported Upstream version 5.1.1
Diffstat (limited to 'src/libstrongswan/threading')
-rw-r--r--src/libstrongswan/threading/rwlock.c16
-rw-r--r--src/libstrongswan/threading/semaphore.c10
2 files changed, 21 insertions, 5 deletions
diff --git a/src/libstrongswan/threading/rwlock.c b/src/libstrongswan/threading/rwlock.c
index 176445705..d7374cddf 100644
--- a/src/libstrongswan/threading/rwlock.c
+++ b/src/libstrongswan/threading/rwlock.c
@@ -27,6 +27,13 @@
#include "mutex.h"
#include "lock_profiler.h"
+#ifdef __APPLE__
+/* while pthread_rwlock_rdlock(3) says that it supports multiple read locks,
+ * this does not seem to be true. After releasing a recursive rdlock,
+ * a subsequent wrlock fails... */
+# undef HAVE_PTHREAD_RWLOCK_INIT
+#endif
+
typedef struct private_rwlock_t private_rwlock_t;
typedef struct private_rwlock_condvar_t private_rwlock_condvar_t;
@@ -254,6 +261,7 @@ METHOD(rwlock_t, read_lock, void,
private_rwlock_t *this)
{
uintptr_t reading;
+ bool old;
reading = (uintptr_t)pthread_getspecific(is_reader);
profiler_start(&this->profile);
@@ -265,10 +273,12 @@ METHOD(rwlock_t, read_lock, void,
}
else
{
+ old = thread_cancelability(FALSE);
while (this->writer || this->waiting_writers)
{
this->readers->wait(this->readers, this->mutex);
}
+ thread_cancelability(old);
}
this->reader_count++;
profiler_end(&this->profile);
@@ -279,13 +289,17 @@ METHOD(rwlock_t, read_lock, void,
METHOD(rwlock_t, write_lock, void,
private_rwlock_t *this)
{
+ bool old;
+
profiler_start(&this->profile);
this->mutex->lock(this->mutex);
this->waiting_writers++;
+ old = thread_cancelability(FALSE);
while (this->writer || this->reader_count)
{
this->writers->wait(this->writers, this->mutex);
}
+ thread_cancelability(old);
this->waiting_writers--;
this->writer = TRUE;
profiler_end(&this->profile);
@@ -417,7 +431,7 @@ METHOD(rwlock_condvar_t, timed_wait_abs, bool,
thread_cleanup_push((thread_cleanup_t)this->mutex->unlock, this->mutex);
timed_out = this->condvar->timed_wait_abs(this->condvar, this->mutex, time);
thread_cleanup_pop(TRUE);
- thread_cleanup_pop(!timed_out);
+ thread_cleanup_pop(TRUE);
return timed_out;
}
diff --git a/src/libstrongswan/threading/semaphore.c b/src/libstrongswan/threading/semaphore.c
index b785ff944..d90588b50 100644
--- a/src/libstrongswan/threading/semaphore.c
+++ b/src/libstrongswan/threading/semaphore.c
@@ -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;
}
-