digitalmars.D.bugs - [Issue 22555] New: Recursively locked mutexes are not fully released
- d-bugmail puremagic.com (84/84) Nov 30 2021 https://issues.dlang.org/show_bug.cgi?id=22555
https://issues.dlang.org/show_bug.cgi?id=22555 Issue ID: 22555 Summary: Recursively locked mutexes are not fully released by Condition.wait Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: enhancement Priority: P1 Component: druntime Assignee: nobody puremagic.com Reporter: default_357-line yahoo.de Consider this code: import std; import core.sync.condition; import core.sync.mutex; import core.sync.semaphore; import core.thread; class A { int value; Condition condition; this() { condition = new Condition(new Mutex(this)); } void set(int i) { synchronized (this) { value = i; this.condition.notifyAll; } } void wait(int i) { synchronized (this) { while (this.value != i) { condition.wait; } } } } void main() { auto done = new Semaphore; auto a = new A; task({ synchronized (a) { writefln!"Wait for a to be 5"; a.wait(5); writefln!"Wait done."; } done.notify; }).executeInNewThread; writefln!"Let task start up."; Thread.sleep(100.msecs); writefln!"Set a to 5."; a.set(5); writefln!"Wait for task to be done."; done.wait; writefln!"Done."; } Naively we would expect this sequence of operations: Thread starts. Thread waits on a.value == 5 main sets a.value to 5 Thread finishes waiting and signals done. Main awaits done and returns. This does not happen on Posix, because pthreads recursive mutexes have a dangerous interaction with condition variables. See https://linux.die.net/man/3/pthread_cond_wait "These functions atomically release _mutex_" in conjunction with https://linux.die.net/man/3/pthread_mutex_lock "Each time the thread unlocks the mutex, the lock count shall be decremented by one. When the lock count reaches zero, the mutex shall become available for other threads to acquire." As demonstrated, the effect of this is that after pthread_cond_wait, the mutex is *not* available for other threads to acquire! This causes the example to block forever. --
Nov 30 2021