On Saturday, 15 December 2018 at 02:54:55 UTC, Heromyth wrote:
We have a module including many globle variables which are needed to be initialized firstly in "shared static this() {}", see here https://github.com/huntlabs/hunt/blob/master/source/hunt/time/Init.d.

The problem is that these variables are not always initialized firstly when are referenced by some others moudles in "static this() {}". Here is a demo to illustrate it.

//////////////////
// module A
//////////////////
module test.A;

import std.stdio;
import core.thread;
import core.time;

class A {
    __gshared int sharedField;

    shared static this() {
writeln("running A in shared static this(), sharedField=", sharedField);

        Thread th = new Thread(() {  });
        th.start();

        Thread.sleep(100.msecs);
        sharedField = 2;
writeln("running A done in shared static this(), sharedField=", sharedField);
    }

    static this() {
writeln("running A in static this(), sharedField=", sharedField);
    }
}

//////////////////
// module B
//////////////////
module test.B;

import test.A;
import std.stdio;
import core.thread;

shared static this() {
    writeln("running in shared static this() from B");
}

class B {
    shared static this() {
writeln("running B in shared static this(), sharedField=", A.sharedField);
    }

    static this() {
        // bug is here
writeln("running B in static this(), sharedField=", A.sharedField);
    }
}

//////////////////
// module main
//////////////////
import std.stdio;

import test.A;
import core.thread;

void main()
{
        writeln("running in main.");
}

//////////////////
// output
//////////////////
Running ./demo
running A in shared static this(), sharedField=0
running A in static this(), sharedField=0
running B in static this(), sharedField=0  // bug is here
running A done in shared static this(), sharedField=2
running in shared static this() from B
running B in shared static this(), sharedField=2
running A in static this(), sharedField=2
running B in static this(), sharedField=2
running main.


====================
You can see the sharedField is 0 in B's static this() at first. If Thread is disabled to run in shared static this(), this problem seems to be fixed.

Some related bugs:
1) https://issues.dlang.org/show_bug.cgi?id=6114
2) https://issues.dlang.org/show_bug.cgi?id=4923

The problem here is that you are creating a new thread in the `shared static this()`.

    shared static this() {
writeln("running A in shared static this(), sharedField=", sharedField); Thread th = new Thread(() { }); // Calls `static this()` including B's `static this()`
        th.start();
        Thread.sleep(100.msecs);
        sharedField = 2;
writeln("running A done in shared static this(), sharedField=", sharedField);
    }

    static this() {
writeln("running A in static this(), sharedField=", sharedField);
    }

Creating a new thread causes those thread's constructor `static this()` to be called. You need to create your threads somewhere else or have the values be initialized before the threads are created.

Reply via email to