On Wed, Jan 4, 2012 at 2:12 PM, Sean Kelly <[email protected]> wrote: > On Dec 23, 2011, at 8:49 PM, Andrew Wiley wrote: > >> On Fri, Dec 23, 2011 at 8:33 PM, Andrew Wiley <[email protected]> >> wrote: >>> On Fri, Dec 23, 2011 at 1:25 AM, Somedude <[email protected]> >>> wrote: >>>> On windows XP with DMD 2.057, I get >>>> Queue1: deadlock >>>> Queue2: works >>>> Queue3: works >>> >>> Yes, I posted another (much shorter) post describing the issue with >>> Queue1. In short, since Queue1 is a synchronized class, the >>> constructor is synchronized (which is mostly worthless). As a >>> consequence, when I replace the lock in the middle of the function, >>> bad things happen when the runtime tries to unlock the lock at the end >>> and sees the new lock. >>> >>> This version of Queue1 shows a very hacky way to get around this: >>> --- >>> synchronized class Queue1 {private: bool _work; Condition >>> _cond;public: this() { auto lock = new Mutex(this); // >>> initialize the monitor for this object so we can use the same lock in >>> the Condition lock.lock(); // HACK: acquire the lock so we can >>> unlock it at the end of the function _cond = new >>> Condition(lock); _work = false; } void doWork() { >>> while(!_work) (cast()_cond).wait(); _work = false; >>> writeln("did work"); return; } void addWork() { _work >>> = true; (cast()_cond).notify(); writeln("added work"); >>> }}--- >>> Queue2 looks like a bug where GDC is acquiring all locks twice in >>> synchronized functions, and since the condition variable only unlocks >>> the lock once, a deadlock results. I'll get a bug report up about it >>> shortly. >> >> Gah, my hacked/fixed Queue1 got garbled: >> --- >> synchronized class Queue1 { >> private: >> bool _work; >> Condition _cond; >> public: >> this() { >> auto lock = new Mutex(this); // initialize the monitor for this >> object > > This assumes that there is no existing monitor for the object. At best > you'll get a memory leak here.
Then is there any way to safely use this sort of idiom? Putting it on the first line of the constructor was the earliest way I could see to try to swap the lock.
