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:
|
private:
|
||||||
|
|
||||||
Genode::Thread *_owner;
|
Genode::Thread *_owner = nullptr;
|
||||||
Genode::Lock _nbr_mutex {};
|
Genode::Lock _nbr_mutex {};
|
||||||
Genode::Lock _global_mutex {};
|
Genode::Lock _global_mutex {};
|
||||||
int _nbr = 0;
|
int _nbr = 0;
|
||||||
@ -51,6 +51,7 @@ extern "C" {
|
|||||||
++_nbr;
|
++_nbr;
|
||||||
if (_nbr == 1) {
|
if (_nbr == 1) {
|
||||||
_global_mutex.lock();
|
_global_mutex.lock();
|
||||||
|
_owner = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,12 +63,12 @@ extern "C" {
|
|||||||
|
|
||||||
int unlock()
|
int unlock()
|
||||||
{
|
{
|
||||||
Genode::Lock_guard<Genode::Lock> guard(_nbr_mutex);
|
|
||||||
|
|
||||||
/* Read lock */
|
/* Read lock */
|
||||||
if (_owner == nullptr) {
|
if (_owner == nullptr) {
|
||||||
|
Genode::Lock_guard<Genode::Lock> guard(_nbr_mutex);
|
||||||
_nbr--;
|
_nbr--;
|
||||||
if (_nbr == 0) {
|
if (_nbr == 0) {
|
||||||
|
_owner = nullptr;
|
||||||
_global_mutex.unlock();
|
_global_mutex.unlock();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -80,6 +81,7 @@ extern "C" {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Write lock owned by us */
|
/* Write lock owned by us */
|
||||||
|
_owner = nullptr;
|
||||||
_global_mutex.unlock();
|
_global_mutex.unlock();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user