diff --git a/src/core/thread.d b/src/core/thread.d index fe05fc3714..f402d0939a 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -596,7 +596,10 @@ class Thread */ ~this() nothrow @nogc { - if ( m_addr == m_addr.init ) + bool no_context = m_addr == m_addr.init; + bool not_registered = !next && !prev && (sm_tbeg !is this); + + if (no_context || not_registered) { return; } @@ -1856,8 +1859,9 @@ private: do { // Thread was already removed earlier, might happen b/c of thread_detachInstance - if (!t.next && !t.prev) + if (!t.next && !t.prev && (sm_tbeg !is t)) return; + slock.lock_nothrow(); { // NOTE: When a thread is removed from the global thread list its diff --git a/test/thread/src/external_threads.d b/test/thread/src/external_threads.d index 087c4bfebd..9c98a3fa13 100644 --- a/test/thread/src/external_threads.d +++ b/test/thread/src/external_threads.d @@ -1,8 +1,12 @@ import core.sys.posix.pthread; import core.memory; +import core.thread; + +extern (C) void rt_moduleTlsCtor(); +extern (C) void rt_moduleTlsDtor(); extern(C) -void* entry_point(void*) +void* entry_point1(void*) { // try collecting - GC must ignore this call because this thread // is not registered in runtime @@ -10,13 +14,37 @@ void* entry_point(void*) return null; } +extern(C) +void* entry_point2(void*) +{ + // This thread gets registered in druntime, does some work and gets + // unregistered to be cleaned up manually + thread_attachThis(); + rt_moduleTlsCtor(); + + auto x = new int[10]; + + rt_moduleTlsDtor(); + thread_detachThis(); + return null; +} + void main() { // allocate some garbage auto x = new int[1000]; - pthread_t thread; - auto status = pthread_create(&thread, null, &entry_point, null); - assert(status == 0); - pthread_join(thread, null); + { + pthread_t thread; + auto status = pthread_create(&thread, null, &entry_point1, null); + assert(status == 0); + pthread_join(thread, null); + } + + { + pthread_t thread; + auto status = pthread_create(&thread, null, &entry_point2, null); + assert(status == 0); + pthread_join(thread, null); + } }