On Sat, 09 May 2015 15:38:05 -0400, Mike <n...@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.digitalmar...@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

Reply via email to