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

Dmitry Olshansky dmitry.olsh at gmail.com
Wed May 30 05:55:10 PDT 2012


On 30.05.2012 16:43, Regan Heath wrote:
> On Wed, 30 May 2012 00:10:19 +0100, Jonathan M Davis
> <jmdavisProg at gmx.com> wrote:
>
>> On Wednesday, May 30, 2012 01:02:53 Alex Rønne Petersen wrote:
>>> But mutexes allow proper encapsulation by hiding the mutex resource. As
>>> I've proven in the very OP of this thread, both druntime and phobos
>>> suffer from the anti-pattern that is locking on a public resource when
>>> you shouldn't. The language encourages doing it with this synchronized
>>> business.
>>
>>> From your comments, it sounds to me like the problem is entirely with
>> synchronized blocks, not sychronized classes. Synchronized classes
>> don't have
>> the issue of having externals lock on them without the explicit use of
>> synchronized blocks. They're the equivalent of locking a mutex in
>> every public
>> function and releasing it afterwards. The problem is that that mutex is
>> effectively public such that when a synchronized block is used on it,
>> it locks
>> on the same mutex. If no synchronized blocks are used, as far as I can
>> tell,
>> it's a non-issue.
>>
>> As such, wouldn't simply making the use of a sychronized block on a
>> synchronized object illegal fix the problem?
>
> Not in all cases. If you have a synchronized class, say a thread-safe
> container, which has a synchronized lookup and synchronized insert
> function, code like..
>
> if (!o.lookup(...))
> o.insert(...)
>
> obtains and releases the mutex twice each, and in between another thread
> could call o.insert() and insert the missing object - resulting in 2
> copies being inserted (or a duplicate insert exception being throw, or...).
>
> Now, the above is bad design, but the only other choice is to expose
> lock() and unlock() methods (or the mutex - back to square 1one) to
> allow locking around multiple class, but now the caller has to be
> careful to call unlock in all code paths. scope helps us in D, but this
> is actually the whole point of synchronized blocks - 1. ensuring the
> unlock always happens and 2. making the scope of the locking visible in
> the code.
>
synchronized class Container
{

void applyLocked(scope delegate void(Container _this));
...
}


-- 
Dmitry Olshansky


More information about the Digitalmars-d mailing list