shared - i need it to be useful

Simen Kjærås simen.kjaras at gmail.com
Thu Oct 18 14:11:10 UTC 2018


On Thursday, 18 October 2018 at 13:35:22 UTC, Steven 
Schveighoffer wrote:
> struct ThreadSafe
> {
>    private int x;
>    void increment()
>    {
>       ++x; // I know this is not shared, so no reason to use 
> atomics
>    }
>    void increment() shared
>    {
>       atomicIncrement(&x); // use atomics, to avoid races
>    }
> }

But this isn't thread-safe, for the exact reasons described 
elsewhere in this thread (and in fact, incorrectly leveled at 
Manu's proposal). Someone could write this code:

void foo() {
     ThreadSafe* a = new ThreadSafe();
     shareAllOver(a);
     a.increment(); // unsafe, non-shared method call
}

When a.increment() is being called, you have no idea if anyone 
else is using the shared interface.

This is one of the issues that MP (Manu's Proposal) tries to deal 
with. Under MP, your code would *not* be considered thread-safe, 
because the non-shared portion may interfere with the shared 
portion. You'd need to write two types:

struct ThreadSafe {
     private int x;
     void increment() shared {
         atomicIncrement(&x);
     }
}

struct NotThreadSafe {
     private int x;
     void increment() {
         ++x;
     }
}

These two are different types with different semantics, and 
forcing them both into the same struct is an abomination.

In your case, the user of your type will need to ensure 
thread-safety. You may not have any control over how he's doing 
things, while you *do* control the code in your own type (and 
module, since that also affects things). Under MP, the type is 
what needs to be thread-safe, and once it is, the chance of a 
user mucking things up is much lower.

--
   Simen


More information about the Digitalmars-d mailing list