xref: /netbsd-src/external/gpl3/gcc/dist/libphobos/testsuite/libphobos.thread/tlsgc_sections.d (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 import core.memory;
2 import core.sync.condition;
3 import core.sync.mutex;
4 import core.thread;
5 
6 __gshared Condition g_cond;
7 __gshared Mutex g_mutex;
8 __gshared int g_step = 0;
9 
10 class C
11 {
~this()12     ~this()
13     {
14         import core.stdc.stdlib;
15         abort();    // this gets triggered although the instance always stays referenced
16     }
17 }
18 
19 C c;
20 
this()21 static this()
22 {
23     c = new C;
24 }
25 
~this()26 static ~this()
27 {
28     import core.memory;
29     GC.free(cast(void*)c); // free without destruction to avoid triggering abort()
30 }
31 
test()32 void test()
33 {
34     assert(c !is null);
35 
36     // notify the main thread of the finished initialization
37     synchronized (g_mutex) g_step = 1;
38     g_cond.notifyAll();
39 
40     // wait until the GC collection is done
41     synchronized (g_mutex) {
42         while (g_step != 2)
43             g_cond.wait();
44     }
45 }
46 
47 
main()48 void main()
49 {
50     g_mutex = new Mutex;
51     g_cond = new Condition(g_mutex);
52 
53     auto th = new Thread(&test);
54     th.start();
55 
56     // wait for thread to be fully initialized
57     synchronized (g_mutex) {
58         while (g_step != 1)
59             g_cond.wait();
60     }
61 
62     // this causes the other thread's C instance to be reaped with the bug present
63     GC.collect();
64 
65     // allow the thread to shut down
66     synchronized (g_mutex) g_step = 2;
67     g_cond.notifyAll();
68 
69     th.join();
70 }
71