On Monday, 8 April 2024 at 19:59:55 UTC, Richard (Rikki) Andrew Cattermole wrote:
>On 09/04/2024 7:43 AM, Dukc wrote:
>My impression is you can't do that, unless the data structure you're using is flawed (well dataStruct.tupleof
of the works to bypass @safe
ty but I don't think it's relevant since it probably needs to be fixed anyway). Pseudocode example?
void thread1() {
shared(Type) var = new shared Type;
sendToThread2(var);
for(;;) {
// I know about var!
}
}
void sentToThread2(shared(Type) var) {
thread2(var);
}
void thread2(shared(Type) var) {
for(;;) {
// I know about var!
}
}
The data structure is entirely irrelevant.
Shared provided no guarantees to stop this.
I see. I thought you were talking about violating the assumptions of the data structure, but you're worried about sharing it between threads. Well, if you don't want to share something between the threads, that's exactly when you don't make it shared
, and mission accomplished!
However, I think you're advocating for something like @live
. That is, a type that's destroyed in RAII fashion but that can be passed from one function to another, without risking dangling references, and you also want it to work between threads.
This is where DIP1040, or if it fails then DIP1014 steps in.
You can have a RAII data structure by disabling the copy constructor, but ownership can to still be passed around with .move
. With either of these two DIPs you can insert code to be executed each time the struct is moved, if you have to.
As for doing this between two threads, you want a data struct that both handles shared
data and is RAII. The struct handle itself can be shared or thread local. Because it's RAII, only one thread can own it. Because it handles shared data, it can be moved between threads. It still needs locking when borrowed, because the ownership could be passed to another thread before the borrowing ends.
No library features can stop it either, unless you want to check ref counts (which won't work cos ya know graphs).
Yes, ref counting is required AFAIK if borrowing is allowed as it probably is. Going to write a separate reply to this.
>You could make it temporally safe with the help of locking, yes. But shared didn't contribute towards that in any way shape or form.
You're partially right: It's possible to design a @safe
shared data structure entirely without shared
. What shared
enables is that bigger part of implementation of the structure can be @safe
, if still very low-level and bug-prone.