Search code examples
multithreadingthisd

The "this" pointer and message receiving in D


The D multithreading model disallows implicit memory sharing, preferring message passing and immutable data. However, the compiler seems to be odd about letting a this pointer through when receiving messages:

import std.concurrency;
import std.stdio;

class Wat {

    int foo;
    Tid workerThread;

    this(int f)
    {
        foo = f;
        workerThread = spawn(&threadedWork);
    }

    // Must be static. This makes sense because otherwise
    // the object (via "this") would be accessible in two threads,
    // and D discourages shared memory,
    // preferring messages and immutable data.
    static void threadedWork()
    {
        // Compiler correctly complains that I can't access a non-static function
        // from inside a static one.
        bar(42);

        while (true) {
            // But this is allowed. What gives?
            receive (
                &bar
            );
        }
    }

    void bar(int bar)
    {
        if (foo == bar)
            writeln("The answer");
    }
}

Why is the compiler allowing me to use a non-static function inside receive? Is this a bug?


Solution

  • Looks like a bug. What happens is &bar gets you a pointer to the method WITHOUT this which has type as a function pointer:

    pragma(msg, typeof(&Wat.bar));
    void function(int bar)
    

    std.concurrency.receive then sees that and says "oh it is a handler for int messages" and accepts it.... not realizing that it also requires a hidden this argument to be passed to it.

    If you try to use it, you'll get a random result/crash if it tries to access any class members because the this pointer is not actually passed to the function, so it accesses random garbage,

    So while I'd say this is a bug... I'm not sure were the bug is. std.concurrency can't tell the difference between a REAL void function(int) and this fake one since the address-of operator doesn't forward information about the hidden this pointer. I think that's the real bug.