This repository was archived by the owner on Oct 12, 2022. It is now read-only.
File tree Expand file tree Collapse file tree 4 files changed +70
-3
lines changed Expand file tree Collapse file tree 4 files changed +70
-3
lines changed Original file line number Diff line number Diff line change @@ -596,7 +596,10 @@ class Thread
596
596
*/
597
597
~this () nothrow @nogc
598
598
{
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)
600
603
{
601
604
return ;
602
605
}
@@ -1856,8 +1859,9 @@ private:
1856
1859
do
1857
1860
{
1858
1861
// 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) )
1860
1863
return ;
1864
+
1861
1865
slock.lock_nothrow();
1862
1866
{
1863
1867
// NOTE: When a thread is removed from the global thread list its
Original file line number Diff line number Diff line change @@ -2384,6 +2384,14 @@ struct Gcx
2384
2384
*/
2385
2385
size_t fullcollect (bool nostack = false ) nothrow
2386
2386
{
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
+
2387
2395
MonoTime start, stop, begin;
2388
2396
2389
2397
if (config.profile)
Original file line number Diff line number Diff line change 1
1
include ../common.mak
2
2
3
- TESTS: =fiber_guard_page
3
+ TESTS: =fiber_guard_page external_threads
4
4
5
5
.PHONY : all clean
6
6
all : $(addprefix $(ROOT ) /,$(addsuffix .done,$(TESTS ) ) )
@@ -11,6 +11,11 @@ $(ROOT)/fiber_guard_page.done: $(ROOT)/%.done : $(ROOT)/%
11
11
$(QUIET )$(TIMELIMIT )$(ROOT ) /$* $(RUN_ARGS ) ; rc=$$? ; [ $$ rc -eq 139 ] || [ $$ rc -eq 138 ]
12
12
@touch $@
13
13
14
+ $(ROOT ) /external_threads.done : $(ROOT ) /% .done : $(ROOT ) /%
15
+ @echo Testing $*
16
+ $(QUIET )$(TIMELIMIT )$(ROOT ) /$*
17
+ @touch $@
18
+
14
19
$(ROOT ) /% : $(SRC ) /% .d
15
20
$(QUIET )$(DMD ) $(DFLAGS ) -of$@ $<
16
21
Original file line number Diff line number Diff line change
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
+ }
You can’t perform that action at this time.
0 commit comments