Temporally safe by default

Dukc ajieskola at gmail.com
Tue Apr 9 07:17:07 UTC 2024


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?
>
> ```d
> 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.


More information about the dip.ideas mailing list