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

Dmitry Olshansky dmitry.olsh at gmail.com
Thu May 31 07:49:52 PDT 2012


>>
>> But this is a protection/visibility issue, which is orthogonal on the
>> locking capability. It's as if you say "int is not good because anyone
>> can overflow it." Okay! Make it private inside a CheckedInt class.
>
> Sorry, that's a bad comparison. CheckedInt is to int, what CheckedMutex
> is to mutex - but I'm not suggesting anything like a CheckedMutex. I'm
> suggesting "mutex" but kept private inside the class /that it locks/.
> Yes, it's a visibility issue, the issue is that the mutex used by
> synchronized classes/methods is too visible/accessible and this opens it
> up for deadlocks which are otherwise impossible.
>

Sure it's awful comparison.


>>
>> So where's the mutex that would be used to synchronize objects that
>> are not synchronizable?
>
> In the wrapper class/struct/object which derives a synchronized
> class/struct from the original. My D foo is not strong enough to just
> come up with valid D code for the idiom on the fly, but essentially you
> wrap the original object in a new object using a template which adds the
> mutex member and the interface methods (lock, tryLock, and unlock)
> required. No, this doesn't work with "final" classes.. but it shouldn't,
> they're final after all. For them you need to add/manage the mutex
> manually - the price you pay for "final".
>

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?

-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list