On 5/30/12 1:31 PM, Steven Schveighoffer wrote:
On Wed, 30 May 2012 15:48:47 -0400, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
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.

Oh yes it is. "Expose the mutex" means "make the two mutex primitive operations lock() and unlock() freely usable against the mutex object".

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.

Yah, it should be only allowed for synchronized classes.

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!".

Not only I might say that, I'm actually gonna say it. 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.

That's shuffling the fundamental issue from client code to library code. This can be done in either approach (synchronized vs. raw mutex), except it's clunkier with raw mutex.

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.

I don't get what this is supposed to prove.


Andrei

Reply via email to