aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2013-10-24 14:46:14 +0200
committerMartin Willi <martin@revosec.ch>2013-10-24 14:53:53 +0200
commit1a20a22d0985120ada7a9010b51bd91b8d98a06d (patch)
tree05e541690de86307d324c12199bace5e33191bed /src
parent181d071363719aa9341f2c0c5a3aca9002d64ac3 (diff)
downloadstrongswan-1a20a22d0985120ada7a9010b51bd91b8d98a06d.tar.bz2
strongswan-1a20a22d0985120ada7a9010b51bd91b8d98a06d.tar.xz
rwlock: Disable thread cancelability while waiting in (fallback) rwlock
An rwlock wait is not a thread cancellation point. As a canceled thread would not have released the mutex, the rwlock would have been left in unusable state.
Diffstat (limited to 'src')
-rw-r--r--src/libstrongswan/threading/rwlock.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/libstrongswan/threading/rwlock.c b/src/libstrongswan/threading/rwlock.c
index 770061bad..b37f80251 100644
--- a/src/libstrongswan/threading/rwlock.c
+++ b/src/libstrongswan/threading/rwlock.c
@@ -261,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);
@@ -272,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);
@@ -286,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);