On Wed, Jan 4, 2012 at 6:12 PM, Sean Kelly <[email protected]> wrote: > On Jan 4, 2012, at 2:55 PM, Andrew Wiley wrote: > >> On Wed, Jan 4, 2012 at 2:12 PM, Sean Kelly <[email protected]> wrote: >>> >>> >>> 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. > > Not currently. The relevant ctor for Mutex actually has an > "assert(o.__monitor is null)" clause in it that simply never triggers because > we ship a "release" build (I hate that label). The problem is that replacing > an existing monitor means a race condition, since other threads might be > trying to lock it or are waiting on it at the time. The real issue is that > the ctor for a synchronized module shouldn't be synchronized, but I'll grant > that it's easier to fix this in user/library code than sort out a compiler > fix. What you can do is: > --- > extern (C) void _d_monitordelete(Object h, bool det); > synchronized class Queue1 { > private: > bool _work; > Condition _cond; > public: > this() { > _d_monitordelete(this, true); > 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; > } > ... > } > --- > Obviously not ideal since it requires a lot of hackery, but it should work as > desired.
I haven't filed a bug yet about constructors for synchronized classes being synchronized. Should I? I believe it's wrong and unhelpful, but I haven't really gotten any feedback and I'm afraid I may have missed something.
