mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-23 23:42:32 +00:00
pthread: fix deadlock in pthread_rwlock_*
Properly initialize and reset the _owner member, otherwise correlating the unlock operation with the respective read/write lock does not work. Move locking the _nbr_mutex in the unlock operation after the owner check. Otherwise, a reader holding that mutex and waiting for the write lock would deadlock a writer trying to unlock the _global_mutex. Ref. Componolit/componolit#86 Ref. #2656 Fixes #2832
This commit is contained in:
parent
230ed1de37
commit
43faf63fde
@ -38,7 +38,7 @@ extern "C" {
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Thread *_owner;
|
||||
Genode::Thread *_owner = nullptr;
|
||||
Genode::Lock _nbr_mutex {};
|
||||
Genode::Lock _global_mutex {};
|
||||
int _nbr = 0;
|
||||
@ -51,6 +51,7 @@ extern "C" {
|
||||
++_nbr;
|
||||
if (_nbr == 1) {
|
||||
_global_mutex.lock();
|
||||
_owner = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,12 +63,12 @@ extern "C" {
|
||||
|
||||
int unlock()
|
||||
{
|
||||
Genode::Lock_guard<Genode::Lock> guard(_nbr_mutex);
|
||||
|
||||
/* Read lock */
|
||||
if (_owner == nullptr) {
|
||||
Genode::Lock_guard<Genode::Lock> guard(_nbr_mutex);
|
||||
_nbr--;
|
||||
if (_nbr == 0) {
|
||||
_owner = nullptr;
|
||||
_global_mutex.unlock();
|
||||
}
|
||||
return 0;
|
||||
@ -80,6 +81,7 @@ extern "C" {
|
||||
};
|
||||
|
||||
/* Write lock owned by us */
|
||||
_owner = nullptr;
|
||||
_global_mutex.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user