On Wed, 30 May 2012 16:56:51 -0400, deadalnix <deadal...@gmail.com> wrote:
Le 30/05/2012 22:31, Steven Schveighoffer a écrit :
On Wed, 30 May 2012 15:48:47 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
To clarify:
On 5/30/12 12:25 PM, Alex Rønne Petersen wrote:
The mutex may not be
directly exposed in the sense that you can obtain a reference (though
in
reality in all compiler implementations, you can), but it is exposed
in
the sense that you can lock and unlock it, which is a mutation of
state
and program flow.
synchronized (object) {
writeln("about to unlock the object");
XXX
writeln("unlocked the object");
}
Replace "XXX" with a construct that unlocks the object.
This is not what we are talking about.
I guess the easiest way to say it is, the API used to "lock and then
subsequently unlock" the mutex. That is, even this:
Object o = new Object;
synchronized(o)
{
}
is exposing the mutex in such a way that you can interfere with the
semantic meaning of the mutex, and cause preventable deadlocks.
It would be preferrable for:
synchronized(o)
{
}
to be an error, unless typeof(o) allows it explicitly.
I gave you a case where you can have a deadlock, even with simple fully
synchronized classes. You might say, "yeah, but all mutexes can have
deadlocks!".
My contention is that if the default is you do *not* expose the mutex to
external callers, there *cannot* be a deadlock.
Here is the example again:
synchronized class A
{
private int _foo;
@property int foo() { return _foo;}
}
synchronized class B
{
private A _a;
@property A a() { return _a;}
void fun() {}
}
void thread(B b)
{
synchronized(b.a)
{
b.fun();
}
}
If synchronized(b.a) is valid, deadlock can occur. If it's invalid,
deadlock *cannot* occur.
-Steve
This cannot remove all deadlocks, but yes, it goes in the right
direction.
All deadlocks involving A and B mutexes. Or if not, can you show how? I
can't see it.
-Steve