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