On May 14, 2013, at 9:09 AM, Heinz <thor...@gmail.com> wrote: > On Monday, 13 May 2013 at 21:04:23 UTC, Juan Manuel Cabo wrote: > >> There is one thing that should definitely added to the documentation, and >> that is what happens when one issues a notify while the thread hasn't yet >> called Condition.wait(). > > I can confirm that under Win32 calling notify() before wait() > internally signals the condition and then calling wait() returns > immediately and actually does not wait. This is the expected > behavior and is actually how Win32 events work.
A Win32 event can be simulated basically like so: class Event { Condition c; bool signaled = false; this() { c = new Condition(new Mutex); } void wait() { synchronized (c.mutex) { while (!signaled) c.wait(); signaled = false; } } void notify() { synchronized (c.mutex) { signaled = true; c.notify(); } } } auto e = new Event; T get() { while (true) { e.wait(); // A -- race here synchronized (m) { if (!m.isEmpty()) return m.take(); } } } void put(T val) { synchronized(m) { m.add(val); } e.notify(); } You'll notice the redundancy here though to combat the race at point A. Generally, you really want to avoid the Win32 model and use the mutex/condition pair directly with your container or whatever. > On Tuesday, 14 May 2013 at 08:58:31 UTC, Dmitry Olshansky wrote: > >> Have to lock it otherwise you have a race condition on a condition variable >> (wow!). > > Ok, i'll lock it just in case. It also makes me feel my code is > more robust. This will do right? > > ... > synchronized(cond.mutex) > cond.notify(); > … Yep. > My internal bool variable that affects the condition (the one > that decides if the consumer thread should wait) must be setable > at any moment by any thread so i leave it outside the lock. Also, > after setting this variable i immediately call notify() with > mutex unlocked. That's why it is working i think. I don't understand what you mean here. If the variable is protected by a lock it can still be set by any thread at any time. Just only one thread at a time. Doing a lock-free write of the variable basically just means that the variable will probably be set eventually, which is rarely what you actually want.