shared - i need it to be useful

Timon Gehr timon.gehr at gmx.ch
Mon Oct 22 13:24:28 UTC 2018


On 22.10.18 14:39, Aliak wrote:
> On Monday, 22 October 2018 at 10:26:14 UTC, Timon Gehr wrote:
>> ---
>> module borked;
>>
>> void atomicIncrement(int* p)@system{
>>     import core.atomic;
>>     atomicOp!("+=",int,int)(*cast(shared(int)*)p,1);
>> }
>>
>> struct Atomic(T){
>>     private T val;
>>     void opUnary(string op : "++")() shared @trusted {
>>         atomicIncrement(cast(T*)&val);
>>     }
>> }
>> void main()@safe{
>>     auto a=new Atomic!int;
>>     import std.concurrency;
>>     spawn((shared(Atomic!int)* a){ ++*a; }, a);
>>     ++a.val; // race
>> }
>> ---
>>
>>
>> Oh no! The author of the @trusted function (i.e. you) did not deliver 
>> on the promise they made!
> 
> hi, if you change the private val in Atomic to be “private shared T 
> val”, is the situation the same?

It's a bit different, because then there is no implicit unshared->shared 
conversion happening, and this discussion is only about that. However, 
without further restrictions, you can probably construct cases where a 
@safe function in one module escapes a private shared(T)* member to 
somewhere else that expects a different synchronization strategy.

Therefore, even if we agree that unshared->shared conversion cannot be 
implicit in @safe code, the 'shared' design is not complete, but it 
would be a good first step to agree that this cannot happen, such that 
we can then move on to harder issues.

E.g. probably it would be good to have something like @trusted data that 
cannot be manipulated from @safe code, such that @trusted functions can 
rely on some invariants.


More information about the Digitalmars-d mailing list