how to assign to shared obj.systime?

Arafel er.krali at gmail.com
Sat Jul 11 10:15:29 UTC 2020


On 10/7/20 20:30, mw wrote:
> On Friday, 10 July 2020 at 17:35:56 UTC, Steven Schveighoffer wrote:
>> Mark your setTime as shared, then cast away shared (as you don't need 
>> atomics once it's locked), and assign:
>>
>> synchronized setTime(ref SysTime t) shared {
>>     (cast()this).time = t;
>> }
> 
> I know I can make it work by casting, my question is:
> 
> we had a lock on the owning shared object already, WHY we still need the 
> cast to make it compile.
> 

Because the system don't know if just this lock is enough to protect 
this specific access. When you have multiple locks protecting multiple 
data, things can become messy.

What I really miss is some way of telling the compiler "OK, I know what 
I'm doing, I'm already in a critical section, and that all the 
synchronization issues have been already managed by me".

Within this block, shared would implicitly convert to non-shared, and 
the other way round, like this (in a more complex setup with a RWlock):

```
setTime(ref SysTime t) shared {
	synchronized(myRWMutex.writer) critical_section {  // From this point I 
can forget about shared
		time = t;
	}
}
```

As a workaround, I have implemented the following trivial helpers:

```
mixin template unshareThis() {
     alias S = typeof(this);
     static if (is(S C == shared C)) {}
     static if (is(S == class) || is(S == interface)) {
         C unshared = cast(C) this;
     } else static if (is(S == struct)) {
         C* unshared = cast(C*) &this;
     } else {
         static assert(0, "Only classes, interfaces and structs can be 
unshared");
     }
}


pragma(inline, true);
ref unshare(S)(return ref S s) {
	static if (is (S C == shared C)) { }
     return *(cast(C*) &s);
}
```

With them you should be able to do either:

```
synchronized setTime(ref SysTime t) shared {
	mixin unshareThis;
	unshared.time = t;
}
```
(useful if you need multiple access), or:

```
synchronized setTime(ref SysTime t) shared {
	time.unshare = t;
}
```


More information about the Digitalmars-d-learn mailing list