Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit ec7b659

Browse files
authored
Merge pull request #2334 from mihails-strasuns/fix-detach-termination
Fix crash in destructor of detached thread merged-on-behalf-of: Nathan Sashihara <n8sh@users.noreply.github.com>
2 parents 1f1cb92 + f0abd06 commit ec7b659

File tree

2 files changed

+39
-7
lines changed

2 files changed

+39
-7
lines changed

src/core/thread.d

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,10 @@ class Thread
596596
*/
597597
~this() nothrow @nogc
598598
{
599-
if ( m_addr == m_addr.init )
599+
bool no_context = m_addr == m_addr.init;
600+
bool not_registered = !next && !prev && (sm_tbeg !is this);
601+
602+
if (no_context || not_registered)
600603
{
601604
return;
602605
}
@@ -1856,8 +1859,9 @@ private:
18561859
do
18571860
{
18581861
// Thread was already removed earlier, might happen b/c of thread_detachInstance
1859-
if (!t.next && !t.prev)
1862+
if (!t.next && !t.prev && (sm_tbeg !is t))
18601863
return;
1864+
18611865
slock.lock_nothrow();
18621866
{
18631867
// NOTE: When a thread is removed from the global thread list its

test/thread/src/external_threads.d

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
11
import core.sys.posix.pthread;
22
import core.memory;
3+
import core.thread;
4+
5+
extern (C) void rt_moduleTlsCtor();
6+
extern (C) void rt_moduleTlsDtor();
37

48
extern(C)
5-
void* entry_point(void*)
9+
void* entry_point1(void*)
610
{
711
// try collecting - GC must ignore this call because this thread
812
// is not registered in runtime
913
GC.collect();
1014
return null;
1115
}
1216

17+
extern(C)
18+
void* entry_point2(void*)
19+
{
20+
// This thread gets registered in druntime, does some work and gets
21+
// unregistered to be cleaned up manually
22+
thread_attachThis();
23+
rt_moduleTlsCtor();
24+
25+
auto x = new int[10];
26+
27+
rt_moduleTlsDtor();
28+
thread_detachThis();
29+
return null;
30+
}
31+
1332
void main()
1433
{
1534
// allocate some garbage
1635
auto x = new int[1000];
1736

18-
pthread_t thread;
19-
auto status = pthread_create(&thread, null, &entry_point, null);
20-
assert(status == 0);
21-
pthread_join(thread, null);
37+
{
38+
pthread_t thread;
39+
auto status = pthread_create(&thread, null, &entry_point1, null);
40+
assert(status == 0);
41+
pthread_join(thread, null);
42+
}
43+
44+
{
45+
pthread_t thread;
46+
auto status = pthread_create(&thread, null, &entry_point2, null);
47+
assert(status == 0);
48+
pthread_join(thread, null);
49+
}
2250
}

0 commit comments

Comments
 (0)