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

Regan Heath regan at netmail.co.nz
Wed May 30 09:03:26 PDT 2012


On Wed, 30 May 2012 16:46:54 +0100, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 5/30/12 2:34 AM, deadalnix wrote:
>> Le 29/05/2012 23:33, Andrei Alexandrescu a écrit :
>>> On 5/29/12 1:37 AM, deadalnix wrote:
>>>> I would say that breaking things here, with the right deprecation
>>>> process, is the way to go.
>>>
>>> So what should we use for mutex-based synchronization if we deprecate
>>> synchronized classes?
>>>
>>> Andrei
>>
>> I think something similar to range design here is the way to go.
>>
>> It is easy to define something like
>>
>> template isLockable(T) {
>> enum isLockable = isShared!T && is(typeof(T.init.lock())) &&
>> is(typeof(T.init.release()));
>> }
>>
>> And allow locking only if(isLockable!Type) .
>>
>> Now we can create SyncObject or any structure we want. The point is that
>> we lock explicit stuff.
>
> But in this design anyone can lock such an object, which was something  
> you advocated against.

I think there is some confusion here as to what the "problem" is and is  
not.

The problem is /not/ that you can lock any object.
The problem is /not/ that we have synchronized(object) {}
The problem is /not/ that we have synchronized classes/methods.

The problem /is/ that synchronized classes/methods use a mutex which is  
exposed publicly, and it the same mutex as used by synchronized(object)  
{}.  This exposure/re-use makes deadlocks more likely to happen, and  
harder to spot.

Removal of this "problem" will not stop deadlocks from happening as  
they're a problem multi-threaded/lock based code will always have (*).  It  
will however make them far less likely to happen accidentally.  It will  
make programmers think about what/where/when and how to lock things rather  
than blithely using synchronized everywhere.  It will mean using locks is  
not as easy as currently, though I think we can make it fairly nice with  
good library code and/or some co-operation between the runtime and  
synchronized() statements i.e. requiring the class implement a common  
Lockable interface for example.

The fact that every object can be locked, and this means they all use more  
memory is a side issue - arguably as important for some.

R

(*) the best you can do to "solve" the deadlock problem is to impose lock  
acquisition ordering on your code, as in all locks must be acquired in a  
defined order, and if not an assertion/error/exception is thrown.  This  
requires some sort of static/singelton/overlord class which is aware of  
all mutexes and is involved in all acquisitions/releases.

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/


More information about the Digitalmars-d mailing list