Skip to content

Commit 619373b

Browse files
committed
add explicit thread_term call to replace atexit
- When calling rt_init/rt_term from ELF's .ctors/.dtors section atexit runs before rt_term, which causes a crash because the thread locks are already destroyed.
1 parent 9a419df commit 619373b

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

src/core/thread.d

+15-6
Original file line numberDiff line numberDiff line change
@@ -1393,13 +1393,12 @@ private:
13931393
lock[] = Mutex.classinfo.init[];
13941394
(cast(Mutex)lock.ptr).__ctor();
13951395
}
1396+
}
13961397

1397-
extern(C) void destroy()
1398-
{
1399-
foreach (ref lock; _locks)
1400-
(cast(Mutex)lock.ptr).__dtor();
1401-
}
1402-
atexit(&destroy);
1398+
static void termLocks()
1399+
{
1400+
foreach (ref lock; _locks)
1401+
(cast(Mutex)lock.ptr).__dtor();
14031402
}
14041403

14051404
__gshared Context* sm_cbeg;
@@ -1726,6 +1725,16 @@ extern (C) void thread_init()
17261725
}
17271726

17281727

1728+
/**
1729+
* Terminates the thread module. No other thread routine may be called
1730+
* afterwards.
1731+
*/
1732+
extern (C) void thread_term()
1733+
{
1734+
Thread.termLocks();
1735+
}
1736+
1737+
17291738
/**
17301739
*
17311740
*/

src/core/thread.di

+7
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,13 @@ private:
436436
extern (C) void thread_init();
437437

438438

439+
/**
440+
* Terminates the thread module. No other thread routine may be called
441+
* afterwards.
442+
*/
443+
extern (C) void thread_term();
444+
445+
439446
/**
440447
*
441448
*/

src/gc/proxy.d

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ private
2929
__gshared gc_t _gc;
3030

3131
extern (C) void thread_init();
32+
extern (C) void thread_term();
3233

3334
struct Proxy
3435
{
@@ -136,8 +137,9 @@ extern (C)
136137
// the problems mentioned above though, so I guess we'll see.
137138
_gc.fullCollectNoStack(); // not really a 'collect all' -- still scans
138139
// static data area, roots, and ranges.
139-
_gc.Dtor();
140+
thread_term();
140141

142+
_gc.Dtor();
141143
free(cast(void*)_gc);
142144
_gc = null;
143145
}

0 commit comments

Comments
 (0)