Synchronization on immutable object

Johan Engelen via Digitalmars-d digitalmars-d at puremagic.com
Tue Mar 22 14:48:55 PDT 2016


On Tuesday, 22 March 2016 at 21:32:24 UTC, Alex Parrill wrote:
> 
> As long as there's no race conditions in the initial creation 
> of the mutex, it shouldn't matter, even though it does 
> internally mutate the object, because it's transparent to 
> developers (unless you're going out of your way to access the 
> internal __monitor field).

Internally, the compiler breaks a language guarantee: it allows 
passing an immutable Object to a function as mutable argument. 
The synchronization object is passed to _d_monitorenter in 
druntime.

An optimizer may use the immutability information, leading to 
troubles.
```
import std.stdio : writeln;
interface Foo {}
void main() {
     writeln(cast(size_t) typeid(Foo).__monitor);
     synchronized(typeid(Foo)) {   }
     writeln(cast(size_t) typeid(Foo).__monitor);
}
```
This prints two zeros for `ldc2 -O3 -run`.  (typeid(Foo) is 
immutable in LDC)
So the optimizer deduces the __monitor pointer is still null, 
even though it no longer is after the synchronized statement.

> What exactly is bugged about the typeid example under LDC?

See https://github.com/ldc-developers/ldc/issues/1377
It is an example proving that synchronizing on an immutable 
object is dangerous.



More information about the Digitalmars-d mailing list