www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Synchronization on immutable object

reply Johan Engelen <j j.nl> writes:
Quiz: does this compile or not?
```
class Klass {}
void main() {
     immutable Klass klass = new Klass;
     synchronized (klass)
     {
         // do smth
     }
}
```

A D object contains two (!) hidden pointers. Two? Yes: the vtable 
pointer __vptr, and a pointer to a Monitor struct which contains 
a synchronization mutex.
The synchronized statement is lowered into druntime calls that 
*write* to __monitor.
Quiz answer: yes it compiles. Oops?

This is related to an earlier discussion on whether TypeInfo 
objects should be immutable or not [1]. Should one be able to 
synchronize on typeid(...) or not?
```
interface Foo {}
void main() {
     synchronized(typeid(Foo)) {
        // do smth
     }
}
```
Because LDC treats the result of typeid as immutable, the code is 
bugged depending on the optimization level.

[1] 
http://forum.dlang.org/post/entjlarqzpfqohvnnwjb forum.dlang.org
Mar 22 2016
next sibling parent Johan Engelen <j j.nl> writes:
Related bug report: https://issues.dlang.org/show_bug.cgi?id=14251
Mar 22 2016
prev sibling next sibling parent reply Alex Parrill <initrd.gz gmail.com> writes:
On Tuesday, 22 March 2016 at 10:49:01 UTC, Johan Engelen wrote:
 Quiz: does this compile or not?
 ```
 class Klass {}
 void main() {
     immutable Klass klass = new Klass;
     synchronized (klass)
     {
         // do smth
     }
 }
 ```

 A D object contains two (!) hidden pointers. Two? Yes: the 
 vtable pointer __vptr, and a pointer to a Monitor struct which 
 contains a synchronization mutex.
 The synchronized statement is lowered into druntime calls that 
 *write* to __monitor.
 Quiz answer: yes it compiles. Oops?

 This is related to an earlier discussion on whether TypeInfo 
 objects should be immutable or not [1]. Should one be able to 
 synchronize on typeid(...) or not?
 ```
 interface Foo {}
 void main() {
     synchronized(typeid(Foo)) {
        // do smth
     }
 }
 ```
 Because LDC treats the result of typeid as immutable, the code 
 is bugged depending on the optimization level.

 [1] 
 http://forum.dlang.org/post/entjlarqzpfqohvnnwjb forum.dlang.org
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). What exactly is bugged about the typeid example under LDC?
Mar 22 2016
parent Johan Engelen <j j.nl> writes:
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.
Mar 22 2016
prev sibling parent reply Dicebot <public dicebot.lv> writes:
On 03/22/2016 12:49 PM, Johan Engelen wrote:
 Quiz: does this compile or not?
tl; dr: most of druntime internal functions bypass qualifiers and are constant source of type system violation bugs. There is a similar violation with `try { throw new immutable Exception; } catch(Exception) { }` and plenty of array appending bugs have been fixed in the past.
Mar 22 2016
parent Johan Engelen <j j.nl> writes:
On Wednesday, 23 March 2016 at 00:11:32 UTC, Dicebot wrote:
 On 03/22/2016 12:49 PM, Johan Engelen wrote:
 Quiz: does this compile or not?
tl; dr: most of druntime internal functions bypass qualifiers and are constant source of type system violation bugs. There is a similar violation with `try { throw new immutable Exception; } catch(Exception) { }` and plenty of array appending bugs have been fixed in the past.
Thanks. Gives some confidence in the correctness of https://github.com/D-Programming-Language/dmd/pull/5564
Mar 23 2016