diff options
author | Martin Willi <martin@revosec.ch> | 2013-10-24 14:46:14 +0200 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2013-10-24 14:53:53 +0200 |
commit | 1a20a22d0985120ada7a9010b51bd91b8d98a06d (patch) | |
tree | 05e541690de86307d324c12199bace5e33191bed /src | |
parent | 181d071363719aa9341f2c0c5a3aca9002d64ac3 (diff) | |
download | strongswan-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.c | 7 |
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); |