Re: How to initialize a globle variable nicely and properly?

2018-12-15 Thread Neia Neutuladh via Digitalmars-d-learn
On Sat, 15 Dec 2018 13:49:03 +, Heromyth wrote:
> Yes, it's very dangerous to create a new thread in shared static this().
> For a big project, it sometimes hard to identify this problem. Maybe,
> the compiler should do something for this, should it?

The runtime, more likely. There are plenty of problems in this vein that 
the compiler can't detect, but the runtime should be able to detect all of 
them.

Filed https://issues.dlang.org/show_bug.cgi?id=19492


Re: How to initialize a globle variable nicely and properly?

2018-12-15 Thread Heromyth via Digitalmars-d-learn
On Saturday, 15 December 2018 at 03:48:15 UTC, Neia Neutuladh 
wrote:

On Sat, 15 Dec 2018 02:54:55 +, Heromyth wrote:

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

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


When you start a D thread, thread-local static constructors get 
run. So don't start threads until your shared static 
constructors finish.


If I encountered something like this, I would set up a queue of 
actions to be run at the start of main() and fill them with 
static constructors. Instead of this static constructor 
creating a thread, it would enqueue a delegate that starts the 
thread.


Yes, it's very dangerous to create a new thread in shared static 
this(). For a big project, it sometimes hard to identify this 
problem. Maybe, the compiler should do something for this, should 
it?


Re: How to initialize a globle variable nicely and properly?

2018-12-14 Thread Neia Neutuladh via Digitalmars-d-learn
On Sat, 15 Dec 2018 02:54:55 +, Heromyth wrote:
>  shared static this() {
>  writeln("running A in shared static this(),
> sharedField=", sharedField);
> 
>  Thread th = new Thread(() {  });
>  th.start();

When you start a D thread, thread-local static constructors get run. So 
don't start threads until your shared static constructors finish.

If I encountered something like this, I would set up a queue of actions to 
be run at the start of main() and fill them with static constructors. 
Instead of this static constructor creating a thread, it would enqueue a 
delegate that starts the thread.


Re: How to initialize a globle variable nicely and properly?

2018-12-14 Thread Rubn via Digitalmars-d-learn

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.


How to initialize a globle variable nicely and properly?

2018-12-14 Thread Heromyth via Digitalmars-d-learn
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