synchronized (this[.classinfo]) in druntime and phobos

Dmitry Olshansky dmitry.olsh at gmail.com
Thu May 31 13:39:33 PDT 2012


On 31.05.2012 18:49, Dmitry Olshansky wrote:
>
> 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.

It could even go one step forward. Though it require a great deal of 
though, here is an initial idea.

So with the above we have  synchronized class with monitor that is 
eagerly initialized (it's the propose of sync-ed class after all to use 
this mutex safely) and ordinary class that don't have it.

Now if we let shared classes to have monitor field lazily initialized 
something interesting shows up. For the moment let's skip painful detail 
of cast(shared).

It's then possible to introduce a restricted version of ownership 
system. Since ever member of shared class is shared or synchronized(?) 
it should be OK to access member of any depth in it by following the 
chain of monitor locks:
(i.e. I'm assuming composition implies "owns" relationship,
this ownership relation comes only for shared types)

shared class A
{
	shared B b;
	...
}

shared class B
{
	shared C c;
	...
}


then:
{
	...
	A a = ....;
	// locks A's monitor, then B's monitor, unlocks A's
	// then C's monitor, unlocks B's
	// then calls do_smth, then unlocks C's
	//all of the above lock/unlock sequence has to be exception proof
	a.b.c.do_smth();

}


Grunted assuming compositon == ownership is wrong in general, but could 
serve as a sensible default. Then weak non-owning references would be 
provided via dirty casting in special wrappers like
{
	NotOwning!(shared T) x;//shared but doesn't own it, thus if
//calling any resource inside of x, we should keep x.monitor locked 
//through out the operation. (unlike in the above case)
}	
...

Obviously it's iteration 1 of idea, it needs to deal with possible 
atomic modifications, cast(shared), etc.


-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list