how does 'shared' affect member variables?

bitwise via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat May 9 13:17:59 PDT 2015


On Sat, 09 May 2015 15:38:05 -0400, Mike <none at none.com> wrote:

> On Saturday, 9 May 2015 at 18:41:59 UTC, bitwise wrote:
>
>> Also, I wasn't able to find any thorough documentation on shared, so if  
>> someone has a link, that would be helpful.
>>
>
> Here are a few interesting links:
>
> Iain Buclaw (lead developer for GDC) with his interpretation:
> http://forum.dlang.org/post/mailman.739.1431034764.4581.digitalmars-d@puremagic.com
>
> Andrei Alexandrescu highlighting a critical flaw with `shared`
> http://forum.dlang.org/post/lruc3n$at1$1@digitalmars.com
>
> "The truth about shared"
> http://p0nce.github.io/d-idioms/#The-truth-about-shared
>
> Interesting deprecation warning in latest compiler (See compiler output):
> http://goo.gl/EGvK72
>
> But I don't know what the semantics are *supposed* to be, and I get the  
> impression noone else knows either.  I'll be watching this thread myself  
> to see if someone can provide some insight.
>
> Mike

So it seems that although it's not properly implemented, it's still not  
completely benign, right?

I am trying to create a shared queue/array of delegates that run on the  
main thread. I don't know if D's 'shared' semantics will affect it or not,  
and whether or not casting to/from shared will cause problems with 'cas'  
or 'atomicStore'

Would the following code work as expected?

A simplified example:

struct SpinLock {
     private int _lock = 0;

     void lock() {
         while(!cas(cast(shared(int)*)&_lock, 0, 1)) {}
     }
     void unlock() {
         atomicStore(*cast(shared(int)*)&_lock, 0);
     }
}

struct LockGuard(T) {
     private T* _lock;

     this(ref T lock) {
         _lock = &lock;
         _lock.lock();
     }
     ~this() {
         _lock.unlock();
     }
}

class App {
public:
     @property public static App instance() {
         return _instance;
     }
     this() {
         assert(!_instance);
         _instance = this;
     }
     ~this() {
         _instance = null;
     }

     void run(void delegate() dg) {
         auto lk = LockGuard!SpinLock(_lock);
         _actions.insertBack(dg);
     }
     void update()
     {
         auto lk = LockGuard!SpinLock(_lock);

         foreach(act; _actions)
             act();

         _actions.clear();
     }
package:
     __gshared App _instance = null;

     SpinLock _lock;
     Array!(void delegate()) _actions;
}


Thread1:
App.instance.run({ doSomething1(); });

Thread2:
App.instance.run({ doSomething2(); });

Main Thread:
App app = new MyAppType();
while(true) {
     app.update();
}


Thanks,
   Bit


More information about the Digitalmars-d-learn mailing list