On Friday, 19 October 2018 at 00:29:01 UTC, Timon Gehr wrote:
On 18.10.18 23:34, Erik van Velzen wrote:
If you have an object which can be used in both a thread-safe and a thread-unsafe way that's a bug or code smell.

Then why do you not just make all members shared? Because with Manu's proposal, as soon as you have a shared method, all members effectively become shared. It just seems pointless to type them as unshared anyway and then rely on convention within @safe code to prevent unsafe accesses. Because, why? It just makes no sense.

Let's assume you have something like this:

module foo;

private shared int sharedState;

struct Accessor {

    int flags;

    void addUser(this T)()   {
       static if (is(T == shared))
sharedState.atomicInc(); // unconditionally increment when it's a shared reference
       else {
// owner may optimize shared access based on it's own state
           if (!(flags & SKIP_LOCKS)) sharedState.atomicInc();
       }
    }

    void removeUser(this T)() {
        static if (is(T == shared))
            sharedState.atomicDec();
        else {
            if (!(flags & SKIP_LOCKS)) sharedState.atomicDec();
        }
    }

    void setFlags(int f) { flags = f; }
}

The 'Accessor' doesn't really hold any shared state, but it accesses a shared module global. Now, the *owner* (e.g. code that instantiated a local Accessor) may use non-`shared` interface to track additional state and make decisions whether or not access the global. A concrete example would be e.g. an I/O lock, where if you know you don't have any threads other than main, you can skip syscalls locking/unlocking the handle.

With the proposal I posted in the beginning, you would then not only get implicit conversion of class references to shared, but also back to unshared.

Is it in your first posts in this thread? I must've skipped that.

I think the conflation of shared member functions and thread safe member functions is confusing. shared on a member function just means that the `this` reference is shared.

Nod.

The only use case for this is overloading on shared. The D approach to multithreading is that /all/ functions should be thread safe, but it is easier for some of them because they don't even need to access any shared state. It is therefore helpful if the type system cleanly separates shared from unshared state.

Nod nod.

Reply via email to