synchronized (this[.classinfo]) in druntime and phobos
Regan Heath
regan at netmail.co.nz
Thu May 31 08:05:59 PDT 2012
On Thu, 31 May 2012 15:49:52 +0100, Dmitry Olshansky
<dmitry.olsh at gmail.com> wrote:
> OK let me land you a hand here. My proposal, that I think fits your
> ideas quite favorably.
>
> I'll enumerate certain assumptions beforehand since it's one of most
> confusing threads I ever followed.
>
> 1. synchronized class means: always allocate hidden monitor mutex, lock
> it on every public method of this class.
>
> 2. synchronized(x,y,z) is lowered to (I use Steven's idea):
> auto sorted = total_order(x,y,z);//conceptual, sorted is tuple of x,y,z
> sorted
> FOR EACH item IN sorted tuple add code in [[ ... ]]
> [[// conceptual
> item.__lock();
> scope(exit) item.__unlock();
> ]]
> In other words it works for every object that defines lock/unlock.
> Multiple object version works only if there is opCmp defined. (by
> address whatever, any total ordering should work)
>
>
> Per definition above synchronized classes AS IS can't be *synchronized*
> on. Instead their public methods are implicitly synchronized.
>
> The end result is:
>
> User can synchronize on various synchronization entities and even plug
> in custom synchronization primitives (say OS Y provides have this fancy
> lock type Z). It's explicit in as sense that object supports it via
> __lock__/unlock. Obviously one still can use __lock/__unlock explicitly
> just don't forget to wear big HERE BE DRAGONS banner.
>
> Synchronized class encapsulate mutex completely - nobody aside from
> designer of the class may (a)use it.
>
> Does it makes sense?
Yes, and it's all more intentional/flexible than what we have now, but.. :)
Does it address what I thought was the main "problem" case. That is, as
soon as you lock 2 objects, one via a synchronized() statement and the
other via a synchronized method you can get a non-obvious deadlock. e.g.
synchronized class A
{
void foo() {} // implicitly locks instance of A
}
class B
{
void __lock() {} // locks instance of B
void __unlock() {} // unlocks instance of B
}
shared A a;
shared B b;
void main()
{
a = new shared(A)();
b = new shared(B)();
..start thread which locks a then b..
synchronized(b) // locks b 'explicitly'
{
a.foo(); // locks a 'implicitly'
}
}
.. but, hang on, can a thread actually lock a and then b? If 'a' cannot
participate in a synchronized statement (which it can't under this
proposal) then no, there is no way to lock 'a' except by calling a
member. So, provided 'a' does not have a member which locks 'b' - were
deadlock safe!
So.. problem solved; by preventing external/public lock/unlock on a
synchronized class. (I think the proposal should enforce this
restriction; synchronized classes cannot define __lock/__unlock).
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list