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

Dmitry Olshansky dmitry.olsh at gmail.com
Thu May 31 13:41:29 PDT 2012


On 01.06.2012 0:39, Dmitry Olshansky wrote:
> 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

s/Grunted/Granted

> 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