Re: Shared with synchronized

2021-04-19 Thread Per Nordlöw via Digitalmars-d-learn

On Monday, 4 March 2019 at 00:07:39 UTC, r-const-dev wrote:
I'm trying to implement a thread safe class, guarding data 
access with synchronized and atomicOp.


To get more help with memory safety checking from the compiler, 
please instead use `@safe` as


```d
import std.typecons : Nullable;

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

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


Re: Shared with synchronized

2019-03-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, March 3, 2019 5:07:39 PM MST r-const-dev via Digitalmars-d-learn 
wrote:
> 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?

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

That's basically what you have to do. shared makes most operations which are
not atomic illegal (it really should make them _all_ illegal, but it doesn't
currently), thereby protecting you from bugs related threading isssues. So,
what you then typically need to do is protect the shared variable with a
mutex and then cast away shared while the mutex is locked so that you can
operate on the object as thread-local. It's then up to the programmer to
ensure that no thread-local references to the shared object escape. So, when
the mutex is released, all of the thread-local references should be gone. It
can be a bit annoying, but it means that your code in general is protected
from threading bugs, and the code that has to actually deal with the
threading issues is segregated (similar to how @safe code doesn't have to
worry about memory issues, and @trusted is then used to allow @system stuff
to be done from @safe code, thereby segregating the code that needs to be
verified for memory issues).

- Jonathan M Davis





Re: Shared with synchronized

2019-03-03 Thread r-const-dev via Digitalmars-d-learn

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);
}



Shared with synchronized

2019-03-03 Thread r-const-dev via Digitalmars-d-learn
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)