| |
| Posted by Steven Schveighoffer in reply to cc | PermalinkReply |
|
Steven Schveighoffer
| On 9/4/22 11:24 PM, cc wrote:
> On Saturday, 3 September 2022 at 14:37:16 UTC, Steven Schveighoffer wrote:
> On 9/2/22 3:15 PM, cc wrote:
> Tried casting away shared as a workaround but I assume that will cause some kind of TLS catastrophe.
I think it will be fine, but you may have an issue. You are returning a non-shared VAL , but your class is shared , which means table , and all the VAL and KEY inside must also be shared .
If you cast away shared you have to put it back upon return.
TLS should not be involved here at all, so there is no problem there.
Alright, so this is safe then?
alias VAL[KEY] T;
auto require(KEY key) {
auto unsharedT = cast(T) table;
auto r = unsharedT.require(key);
table = cast(shared) unsharedT;
return cast(shared) r;
}
I think that is fine-ish. You still don't have a shared KEY there. But it really depends on what KEY is. Most likely it's fine (e.g. if KEY is string). If you don't ever really fetch anything out of the key, and just use it to map to your values, I think it should be fine.
> Was a bit surprised to see mutating unsharedT left table unchanged and needed reassigning.
Yes, because before an AA contains an element, it is a null AA. When you add the first element, it's allocated. When you make a copy of a null AA, it doesn't affect the original.
You can fix this by reinterpret casting the AA instead of copying it:
auto r = .require(*(cast(T*)&table), key);
// I think this might also work:
auto r = (cast()table).require(key);
-Steve
|