xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/testsuite/libphobos.thread/tlsgc_sections.d (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1*b1e83836Smrg import core.memory;
2*b1e83836Smrg import core.sync.condition;
3*b1e83836Smrg import core.sync.mutex;
4*b1e83836Smrg import core.thread;
5*b1e83836Smrg 
6*b1e83836Smrg __gshared Condition g_cond;
7*b1e83836Smrg __gshared Mutex g_mutex;
8*b1e83836Smrg __gshared int g_step = 0;
9*b1e83836Smrg 
10*b1e83836Smrg class C
11181254a7Smrg {
~this()12181254a7Smrg     ~this()
13181254a7Smrg     {
14181254a7Smrg         import core.stdc.stdlib;
15*b1e83836Smrg         abort();    // this gets triggered although the instance always stays referenced
16181254a7Smrg     }
17181254a7Smrg }
18181254a7Smrg 
19*b1e83836Smrg C c;
20181254a7Smrg 
this()21181254a7Smrg static this()
22181254a7Smrg {
23*b1e83836Smrg     c = new C;
24181254a7Smrg }
25181254a7Smrg 
~this()26181254a7Smrg static ~this()
27181254a7Smrg {
28181254a7Smrg     import core.memory;
29*b1e83836Smrg     GC.free(cast(void*)c); // free without destruction to avoid triggering abort()
30181254a7Smrg }
31181254a7Smrg 
test()32*b1e83836Smrg void test()
33181254a7Smrg {
34*b1e83836Smrg     assert(c !is null);
35*b1e83836Smrg 
36*b1e83836Smrg     // notify the main thread of the finished initialization
37*b1e83836Smrg     synchronized (g_mutex) g_step = 1;
38*b1e83836Smrg     g_cond.notifyAll();
39*b1e83836Smrg 
40*b1e83836Smrg     // wait until the GC collection is done
41*b1e83836Smrg     synchronized (g_mutex) {
42*b1e83836Smrg         while (g_step != 2)
43*b1e83836Smrg             g_cond.wait();
44181254a7Smrg     }
45*b1e83836Smrg }
46*b1e83836Smrg 
47181254a7Smrg 
main()48181254a7Smrg void main()
49181254a7Smrg {
50*b1e83836Smrg     g_mutex = new Mutex;
51*b1e83836Smrg     g_cond = new Condition(g_mutex);
52181254a7Smrg 
53*b1e83836Smrg     auto th = new Thread(&test);
54*b1e83836Smrg     th.start();
55*b1e83836Smrg 
56*b1e83836Smrg     // wait for thread to be fully initialized
57*b1e83836Smrg     synchronized (g_mutex) {
58*b1e83836Smrg         while (g_step != 1)
59*b1e83836Smrg             g_cond.wait();
60*b1e83836Smrg     }
61*b1e83836Smrg 
62*b1e83836Smrg     // this causes the other thread's C instance to be reaped with the bug present
63*b1e83836Smrg     GC.collect();
64*b1e83836Smrg 
65*b1e83836Smrg     // allow the thread to shut down
66*b1e83836Smrg     synchronized (g_mutex) g_step = 2;
67*b1e83836Smrg     g_cond.notifyAll();
68*b1e83836Smrg 
69*b1e83836Smrg     th.join();
70181254a7Smrg }
71