I am few days old in playin with D2 and whole shared stuff, so I am probably
wrong in something.
You should probably declare your example class MyValue synchronized instead of
shared. It implies that class is shared too, and this way all methods are
synchronized. In D1 you could mix synchronized and non syncrhonized methods in
class, in D2 its whole or nothing. This way you don't need _lock var in your
example.
So this would work (i guess)
synchronized class MyValue {
int inc() {
return _value++;
}
int get() {
return _value;
}
private int _value;
}
shared MyValue sharedVal;
void main(){
sharedVal = new shared(MyValue );
}
I noticed that in D1 synchronized methods of same class share same lock, while
in this D2 example (when the whole class is declared synchronized), each method
has its own lock.
> Also, is there any documentation on the actual semantics of shared?
> http://www.digitalmars.com/d/2.0/attribute.html is a blank on the subject,
> and the "migrating to shared" article only talks about simple global state.
> What are the actual semantics of shared classes, and how do they interact
> with other code? For instance, after much banging of my head against the
> desk, I finally wrote a working implementation of a simple shared
> multi-reader var. Obviously there are better ways to do a simple shared
> incrementing counter, this is just a first experiment working toward a shared
> mutable 512MB trie data structure that we have in our app's current C++
> implementation:
>
> > shared class MyValue {
> > this() {
> > _lock = cast(shared)new ReadWriteMutex;
> > }
> >
> > int inc() {
> > synchronized((cast(ReadWriteMutex)_lock).writer) {
> > return _value++;
> > }
> > }
> >
> > int get() {
> > synchronized((cast(ReadWriteMutex)_lock).reader) {
> > return _value;
> > }
> > }
> >
> > private ReadWriteMutex _lock;
> > private int _value;
> > }
> >
> > shared MyValue sharedVal;
> > ... seems to behave correctly with multiple threads reading and writing ...
>
> So I can maybe understand the cast(shared) in the ctor. But I have to admit I
> have absolutely no idea why I had to cast away the shared attribute in the
> inc/get methods. Is there any documentation on what's really going on in the
> compiler here? It's a shared method, accessing a shared instance var, why the
> cast? Is the compiler upset about something in the definition of
> ReadWriteMutex itself?
>
> Also, how would one implement this as a struct? My postblit op generates
> compiler errors about casting between shared/unshared MyValue:
>
> > shared struct MyValue {
> > this(this) { _lock = cast(shared) new ReadWriteMutex; } // ERROR
> > ... same as above ...
> > }
>
> I recognize the possible race conditions here, but there has to be *some* way
> to implement a postblit op on a shared struct?
>
> I hope this doesn't come across as empty complaining, I'm happy to help
> improve the documentation if I can.