Some Issues With Synchronized
Andrew Wiley
wiley.andrew.j at gmail.com
Wed Jan 4 14:55:15 PST 2012
On Wed, Jan 4, 2012 at 2:12 PM, Sean Kelly <sean at invisibleduck.org> wrote:
> On Dec 23, 2011, at 8:49 PM, Andrew Wiley wrote:
>
>> On Fri, Dec 23, 2011 at 8:33 PM, Andrew Wiley <wiley.andrew.j at gmail.com> wrote:
>>> On Fri, Dec 23, 2011 at 1:25 AM, Somedude <lovelydear at mailmetrash.com> 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.
More information about the Digitalmars-d
mailing list