On 01.10.2018 04:29, Manu wrote:
struct Bob
{
void setThing() shared;
}
As I understand, `shared` attribution intends to guarantee that I dun
synchronisation internally.
This method is declared shared, so if I have shared instances, I can
call it... because it must handle thread-safety internally.
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.
So, I know that there's not a bunch of threads banging on this
object... but the shared method should still work! A method that
handles thread-safety doesn't suddenly not work when it's only
accessed from a single thread.
...
shared on a method does not mean "this function handles thread-safety".
It means "the `this` pointer of this function is not guaranteed to be
thread-local". You can't implicitly create an alias of a reference that
is supposed to be thread-local such that the resulting reference can be
freely shared among threads.
I feel like I don't understand the design...
mutable -> shared should work the same as mutable -> const... because
surely that's safe?
No. The main point of shared (and the main thing you need to understand)
is that it guarantees that if something is _not_ `shared` is is not
shared among threads. Your analogy is not correct, going from
thread-local to shared is like going from mutable to immutable.
If the suggested typing rule was implemented, we would have the
following way to break the type system, allowing arbitrary aliasing
between mutable and shared references, completely defeating `shared`:
class C{ /*...*/ }
shared(C) sharedGlobal;
struct Bob{
C unshared;
void setThing() shared{
sharedGlobal=unshared;
}
}
void main(){
C c = new C(); // unshared!
Bob(c).setThing();
shared(D) d = sharedGlobal; // shared!
assert(c !is d); // would fail (currently does not even compile)
// sendToOtherThread(d);
// c.someMethod(); // (potential) race condition on unshared data
}