base: minimize critical section in Semaphore::up

When unblocking a thread in Semaphore::up() while holding the fifo meta-data
lock, it might happen that the lock holder gets destroyed by the one it was
unblocking. This happened for instance in the pthread test in the past, where
thread destruction was synchronized via a semaphore. There is no need to hold
the lock during the unblock operation, so we should do it outside the critical
section.

Fix #1333
This commit is contained in:
Stefan Kalkowski 2015-12-03 11:25:11 +01:00 committed by Christian Helmuth
parent 9efa3ceccf
commit 23f9761297
1 changed files with 15 additions and 10 deletions

View File

@ -61,18 +61,23 @@ class Genode::Semaphore
*/
void up()
{
Lock::Guard lock_guard(_meta_lock);
Element * element = nullptr;
if (++_cnt > 0)
return;
{
Lock::Guard lock_guard(_meta_lock);
/*
* Remove element from queue and wake up the corresponding
* blocking thread
*/
Element * element = _queue.dequeue();
if (element)
element->wake_up();
if (++_cnt > 0)
return;
/*
* Remove element from queue and wake up the corresponding
* blocking thread
*/
element = _queue.dequeue();
}
/* do not hold the lock while unblocking a waiting thread */
if (element) element->wake_up();
}
/**