Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

unexpected sync.Condition behaviors

Moderators: kris

Posted: 12/07/09 23:49:07

The first thing I was surprised by but now I'm not sure if it is expected behavior is that the mutex associated with the Condition has to be held before calling Condition.wait or wait will never return (e.g. if the synchronized statement in the example below is removed "Thread A" will only be printed once).

The second, is that the example below throws an OutOfMemoryException? shortly after the first condition.notify call is made. I don't understand what might be causing this.

import tango.core.Thread;
import tango.core.sync.Mutex;
import tango.core.sync.Condition;
import tango.io.Stdout;

Mutex mutex;
Condition condition;

void run()
{
    while(true)
    {
        synchronized (mutex)
        {
            Stdout("Thread A").newline;
            condition.wait(1);
        }
    }
}

void main(char[][] args)
{
    mutex = new Mutex();
    condition = new Condition(mutex);
    auto a = new Thread(&run);
    a.start();
    while(true)
    {
        Thread.sleep(5);
        Stdout("Main thread").newline;
        condition.notify();
    }
}
Author Message

Posted: 12/08/09 09:21:21

I tried your example. There's no allocation in the loop that I can see, so the OutOfMemoryException? is caused by something else. Using the mutex to guard the use of Stdout fixes it, so it's some kind of race condition or other conflict caused by threading. Using Trace instead of Stdout works too, as that is sync'ed.

As for you first question: Condition.wait automatically unlocks the mutex when it's called, and then relocks it again when returning. So it doesn't make sense to call wait unless you have locked the mutex first. There's lots of information on the web about condition variables if you need to know more.

Posted: 12/08/09 17:15:54

Ahh, Ok. I had assumed Stdout's non-thread safeness would just lead to incorrect or mingled output.