[Issue 22555] New: Recursively locked mutexes are not fully released by Condition.wait
d-bugmail at puremagic.com
d-bugmail at puremagic.com
Tue Nov 30 11:54:38 UTC 2021
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 at puremagic.com
Reporter: default_357-line at 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.
--
More information about the Digitalmars-d-bugs
mailing list