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