On Wed, 30 May 2012 00:10:19 +0100, Jonathan M Davis <jmdavisp...@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.

R

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

Reply via email to