Some Issues With Synchronized
Andrew Wiley
wiley.andrew.j at gmail.com
Fri Dec 23 20:49:42 PST 2011
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
// 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");
}
}
---
More information about the Digitalmars-d
mailing list