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.
This commit is contained in:
Martin Willi
2013-10-24 14:53:53 +02:00
parent 181d071363
commit 1a20a22d09
+7
View File
@@ -261,6 +261,7 @@ METHOD(rwlock_t, read_lock, void,
private_rwlock_t *this) private_rwlock_t *this)
{ {
uintptr_t reading; uintptr_t reading;
bool old;
reading = (uintptr_t)pthread_getspecific(is_reader); reading = (uintptr_t)pthread_getspecific(is_reader);
profiler_start(&this->profile); profiler_start(&this->profile);
@@ -272,10 +273,12 @@ METHOD(rwlock_t, read_lock, void,
} }
else else
{ {
old = thread_cancelability(FALSE);
while (this->writer || this->waiting_writers) while (this->writer || this->waiting_writers)
{ {
this->readers->wait(this->readers, this->mutex); this->readers->wait(this->readers, this->mutex);
} }
thread_cancelability(old);
} }
this->reader_count++; this->reader_count++;
profiler_end(&this->profile); profiler_end(&this->profile);
@@ -286,13 +289,17 @@ METHOD(rwlock_t, read_lock, void,
METHOD(rwlock_t, write_lock, void, METHOD(rwlock_t, write_lock, void,
private_rwlock_t *this) private_rwlock_t *this)
{ {
bool old;
profiler_start(&this->profile); profiler_start(&this->profile);
this->mutex->lock(this->mutex); this->mutex->lock(this->mutex);
this->waiting_writers++; this->waiting_writers++;
old = thread_cancelability(FALSE);
while (this->writer || this->reader_count) while (this->writer || this->reader_count)
{ {
this->writers->wait(this->writers, this->mutex); this->writers->wait(this->writers, this->mutex);
} }
thread_cancelability(old);
this->waiting_writers--; this->waiting_writers--;
this->writer = TRUE; this->writer = TRUE;
profiler_end(&this->profile); profiler_end(&this->profile);