On 10/01/2018 04:29 AM, Manu wrote:
struct Bob
{
void setThing() shared;
}
[...]
void f(ref shared Bob a, ref Bob b)
{
a.setThing(); // I have a shared object, can call shared method
b.setThing(); // ERROR
}
This is the bit of the design that doesn't make sense to me...
The method is shared, which suggests that it must handle
thread-safety. My instance `b` is NOT shared, that is, it is
thread-local.
[...]
I feel like I don't understand the design...
mutable -> shared should work the same as mutable -> const... because
surely that's safe?
`shared` isn't analogous to `const`. It's analogous to `immutable`.
Functions dealing with `shared` data can assume that other threads also
see the data as `shared`. If you allow calling `shared` methods on
non-`shared` objects, you're breaking that.
Example:
----
struct Bob
{
int* p;
void doThing() shared
{
p = &s;
}
}
shared int s;
void main()
{
Bob bob;
(cast(shared Bob)bob).doThing();/* You'd make the cast implicit. */
import core.thread;
import core.atomic;
enum n = 1_000_000;
auto t = new Thread(() { foreach (i; 0 .. n) atomicOp!"+="(s, 1); });
t.start();
foreach (i; 0 .. n) ++*bob.p;
thread_joinAll();
import std.stdio;
writeln(s); /* usually not "2000000", because of race */
}
----