On Tue, 29 May 2012 00:36:13 +0200, Alex Rønne Petersen <a...@lycus.org> wrote:

Hi,

I've seen several occurrences of synchronized (this) and synchronized (this.classinfo) in both druntime and phobos by now. I propose that we officially ban these patterns with extreme prejudice.

1) Locking on the object instance is a HORRIBLE IDEA. Anyone who happens to use the object for locking will most likely end up with a deadlock on their hands.

2) Locking on something as fundamental as type info means that any arbitrary part of the application could cause a deadlock by doing the same.
All occurences of this pattern use it to obtain a global unique nameable mutex.
It's a little ugly but I fail to see fundamental issues.

synchronized(Stacktrace.classinfo)
synchronized(typeid(ArrayAllocLengthLock)) // uses an exclusive type as named mutex
synchronized(TaskPool.classinfo)
synchronized(this.classinfo) // this a.k.a. Socket

Then there is std.concurrency.registryLock which is used in the exact same ways as the occurences above. To do that it requires 6 lines of code, has to successfully avoid 2 pitfalls and allocates the mutex eagerly.

Then there is core.thread which has a lot of issues with locking.

There is some suspicious code in object.rt_attachDisposeEvent
which synchronizes on it's argument.

I'm inclined to say that this is a very thin backing for such a rant.


There was one interesting argument by Regan Heath:

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.

Now I do not see anyone synchronizing it's code on arbitrary objects or any
other kind of abuse that would increase the inherent possibility for deadlocks.

Reply via email to