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

Commit 4387aca

Browse files
authored
Merge pull request #2339 from MartinNowak/merge_stable
Merge remote-tracking branch 'upstream/stable' into merge_stable
2 parents f7c61c5 + 02969e8 commit 4387aca

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
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

src/gc/impl/conservative/gc.d

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,14 @@ struct Gcx
23842384
*/
23852385
size_t fullcollect(bool nostack = false) nothrow
23862386
{
2387+
// It is possible that `fullcollect` will be called from a thread which
2388+
// is not yet registered in runtime (because allocating `new Thread` is
2389+
// part of `thread_attachThis` implementation). In that case it is
2390+
// better not to try actually collecting anything
2391+
2392+
if (Thread.getThis() is null)
2393+
return 0;
2394+
23872395
MonoTime start, stop, begin;
23882396

23892397
if (config.profile)

test/thread/Makefile

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include ../common.mak
22

3-
TESTS:=fiber_guard_page
3+
TESTS:=fiber_guard_page external_threads
44

55
.PHONY: all clean
66
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
@@ -11,6 +11,11 @@ $(ROOT)/fiber_guard_page.done: $(ROOT)/%.done : $(ROOT)/%
1111
$(QUIET)$(TIMELIMIT)$(ROOT)/$* $(RUN_ARGS); rc=$$?; [ $$rc -eq 139 ] || [ $$rc -eq 138 ]
1212
@touch $@
1313

14+
$(ROOT)/external_threads.done: $(ROOT)/%.done : $(ROOT)/%
15+
@echo Testing $*
16+
$(QUIET)$(TIMELIMIT)$(ROOT)/$*
17+
@touch $@
18+
1419
$(ROOT)/%: $(SRC)/%.d
1520
$(QUIET)$(DMD) $(DFLAGS) -of$@ $<
1621

test/thread/src/external_threads.d

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import core.sys.posix.pthread;
2+
import core.memory;
3+
import core.thread;
4+
5+
extern (C) void rt_moduleTlsCtor();
6+
extern (C) void rt_moduleTlsDtor();
7+
8+
extern(C)
9+
void* entry_point1(void*)
10+
{
11+
// try collecting - GC must ignore this call because this thread
12+
// is not registered in runtime
13+
GC.collect();
14+
return null;
15+
}
16+
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+
32+
void main()
33+
{
34+
// allocate some garbage
35+
auto x = new int[1000];
36+
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+
}
50+
}

0 commit comments

Comments
 (0)