On Sunday, 3 March 2019 at 22:35:54 UTC, r-const-dev wrote:
I'm trying to implement a thread safe class, guarding data access with synchronized and atomicOp.

Inside the class I'm using non-shared fields, such as Nullable, but I guarantee the thread safety using synchronized. How can I tell the compiler to allow using non-shared fields/methods inside synchronized?

Here is my example:

import core.atomic : atomicOp;
import std.typecons : Nullable;

class SharedObject {
    private Object lock = new Object();
    private Nullable!int sharedValue;
    private int changeCount = 0;
    synchronized void modifyValue(int newValue) {
        sharedValue = newValue;
        atomicOp!("+=")(changeCount, 1);
    }
}

void main()
{
    shared SharedObject data = new shared SharedObject();
    data.modifyValue(3);
}

I get the error:
onlineapp.d(9): Error: template std.typecons.Nullable!int.Nullable.opAssign cannot deduce function from argument types !()(int) shared, candidates are:
/dlang/dmd/linux/bin64/../../src/phobos/std/typecons.d(2884):
   std.typecons.Nullable!int.Nullable.opAssign()(T value)

Found a solution, hope it is a recommended one: cast `this` to non-shared and invoke an "unsafe" method. Inside everything is allowed:



import std.typecons : Nullable;

class SharedObject {
    private Nullable!int sharedValue;
    private int changeCount = 0;
    synchronized void modifyValue(int newValue) {
        (cast(SharedObject)this).unsafeModifyValue(newValue);
    }
    private void unsafeModifyValue(int newValue) {
        sharedValue = newValue;
        ++changeCount;
    }
}

void main()
{
    shared SharedObject data = new shared SharedObject();
    data.modifyValue(3);
}

Reply via email to