synchronized (this[.classinfo]) in druntime and phobos
Regan Heath
regan at netmail.co.nz
Fri Jun 1 05:55:30 PDT 2012
On Thu, 31 May 2012 19:29:27 +0100, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> On 5/31/12 7:01 AM, Regan Heath wrote:
>> Sorry, I have no spare time to spare. You're getting free ideas/thoughts
>> from me, feel free to ignore them.
>
> Thanks. Let me know if I understand correctly that your idea boils down
> to "I don't like synchronized, let's deprecate it and get back to
> core.sync.mutex and recommend the private thingamaroo." In that case, I
> disagree. I believe synchronized has good merits that are being ignored.
To present this another way..
Your motivation for the construct: "synchronized(a, b, ...)" was to
prevent deadlocks caused by:
[thread1]
synchronized(a)
{
synchronized(b)
{
}
}
[thread2]
synchronized(b)
{
synchronized(a)
{
}
}
right?
Well, this is the same problem expressed several other less-obvious (to
code inspection) ways:
1.
[thread1]
synchronized(a)
{
b.foo(); // where b.foo is { synchronized(this) { ... } }
}
[thread2]
synchronized(b)
{
a.foo(); // where a.foo is { synchronized(this) { ... } }
}
2.
[thread1]
synchronized(a)
{
b.foo(); // where b.foo is synchronized void foo() { ... }
}
[thread2]
synchronized(b)
{
a.foo(); // where a.foo is synchronized void foo() { ... }
}
#1 can be solved (in most/many cases) by doing 2 things, first by
disallowing that idiom completely in favour of synchronized classes/class
methods (which I think TDPL does?), and second by adding more control as
described below in(#2)
#2 can be solved (in most/many cases) by allowing greater control over who
can participate in synchronized statements. If either 'a' or 'b' were not
allowed to participate in a synchronized statement, then either thread1 or
thread2 would be invalid code and a deadlock involving these 2 objects
would be impossible(*).
There will still exist some synchronized classes which want to participate
in synchronized statements but I'm thinking/hoping this is rare and if the
default for D is 'not allowed' then it becomes a conscious choice and we
can supply the developer with a warning in the docs which describe how to
do it, introduce the synchronized(a, b, ...) construct, etc.
From another angle.. I'm guessing it's either impossible or very hard to
detect the 2 cases presented above at compile time? Essentially the
compiler would need to know which code could execute in separate threads,
then determine lock ordering for all shared/lockable objects, then detect
cases of both (lock a, b) and (lock b, a) in separate threads. Sounds
tricky.
R
(*)using synchronized statements - one could still keep a reference to the
other internally and call a synchronized member function from within a
synchronized member function
--
Using Opera's revolutionary email client: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list