From 25b68995b280a5e02a758aa0e66aa25cc412da50 Mon Sep 17 00:00:00 2001 From: Stanislav Blinov Date: Sun, 9 Feb 2014 10:32:21 +0400 Subject: [PATCH 1/4] Fix for issue 11981 --- src/core/thread.d | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 8b103ee03f..37198b0d47 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -248,13 +248,23 @@ else version( Posix ) } assert( obj ); - assert( obj.m_curr is &obj.m_main ); - obj.m_main.bstack = getStackBottom(); - obj.m_main.tstack = obj.m_main.bstack; - obj.m_tlsgcdata = rt.tlsgc.init(); - - obj.m_isRunning = true; - Thread.setThis( obj ); + { + // Manually enter and exit critical region, bypassing + // thread_enter/exitCriticalRegion() calls. + // This is needed to disallow suspending this thread + // until it has been initialized. Manual entry and exit + // avoids TLS access (see issue 11981). + synchronized(Thread.criticalRegionLock) obj.m_isInCriticalRegion = true; + scope( exit ) synchronized(Thread.criticalRegionLock) obj.m_isInCriticalRegion = false; + + assert( obj.m_curr is &obj.m_main ); + obj.m_main.bstack = getStackBottom(); + obj.m_main.tstack = obj.m_main.bstack; + obj.m_tlsgcdata = rt.tlsgc.init(); + + obj.m_isRunning = true; + Thread.setThis( obj ); + } //Thread.add( obj ); scope( exit ) { From 399b171c2da5c49b2aef57b3bb7c221562becf78 Mon Sep 17 00:00:00 2001 From: Stanislav Blinov Date: Mon, 10 Feb 2014 19:22:39 +0400 Subject: [PATCH 2/4] Switch to using pthread_key_t for Thread reference on Posix --- src/core/thread.d | 71 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 37198b0d47..2e4f3a72f7 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -248,23 +248,13 @@ else version( Posix ) } assert( obj ); - { - // Manually enter and exit critical region, bypassing - // thread_enter/exitCriticalRegion() calls. - // This is needed to disallow suspending this thread - // until it has been initialized. Manual entry and exit - // avoids TLS access (see issue 11981). - synchronized(Thread.criticalRegionLock) obj.m_isInCriticalRegion = true; - scope( exit ) synchronized(Thread.criticalRegionLock) obj.m_isInCriticalRegion = false; - - assert( obj.m_curr is &obj.m_main ); - obj.m_main.bstack = getStackBottom(); - obj.m_main.tstack = obj.m_main.bstack; - obj.m_tlsgcdata = rt.tlsgc.init(); - - obj.m_isRunning = true; - Thread.setThis( obj ); - } + assert( obj.m_curr is &obj.m_main ); + obj.m_main.bstack = getStackBottom(); + obj.m_main.tstack = obj.m_main.bstack; + obj.m_tlsgcdata = rt.tlsgc.init(); + + obj.m_isRunning = true; + Thread.setThis( obj ); //Thread.add( obj ); scope( exit ) { @@ -1076,7 +1066,19 @@ class Thread // NOTE: This function may not be called until thread_init has // completed. See thread_suspendAll for more information // on why this might occur. - return sm_this; + version( Posix ) + { + // On Posix, pthread_key_t is explicitly used to + // store and access thread reference. This is needed + // to avoid TLS access in signal handlers (malloc deadlock) + // when using shared libraries, see issue 11981. + auto t = cast(Thread) pthread_getspecific( sm_this ); + return t; + } + else + { + return sm_this; + } } @@ -1235,7 +1237,18 @@ private: // // Local storage // - static Thread sm_this; + version( Posix ) + { + // On Posix, pthread_key_t is explicitly used to + // store and access thread reference. This is needed + // to avoid TLS access in signal handlers (malloc deadlock) + // when using shared libraries, see issue 11981. + __gshared pthread_key_t sm_this; + } + else + { + static Thread sm_this; + } // @@ -1284,7 +1297,18 @@ private: // static void setThis( Thread t ) { - sm_this = t; + version( Posix ) + { + // On Posix, pthread_key_t is explicitly used to + // store and access thread reference. This is needed + // to avoid TLS access in signal handlers (malloc deadlock) + // when using shared libraries, see issue 11981. + pthread_setspecific( sm_this, cast(void*) t ); + } + else + { + sm_this = t; + } } @@ -1764,6 +1788,13 @@ extern (C) void thread_init() status = sem_init( &suspendCount, 0, 0 ); assert( status == 0 ); + + // On Posix, pthread_key_t is explicitly used to + // store and access thread reference. This is needed + // to avoid TLS access in signal handlers (malloc deadlock) + // when using shared libraries, see issue 11981. + status = pthread_key_create( &Thread.sm_this, null ); + assert( status == 0 ); } Thread.sm_main = thread_attachThis(); } From 1f0ac4fdebb33c2765f1f75e7423fbeab19eb8a3 Mon Sep 17 00:00:00 2001 From: Stanislav Blinov Date: Mon, 10 Feb 2014 23:06:01 +0400 Subject: [PATCH 3/4] pthread_key_delete(); Don't use pthread_key_t on OSX --- src/core/thread.d | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/core/thread.d b/src/core/thread.d index 2e4f3a72f7..6730dff8c2 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -1052,7 +1052,6 @@ class Thread // Thread Accessors /////////////////////////////////////////////////////////////////////////// - /** * Provides a reference to the calling thread. * @@ -1066,12 +1065,12 @@ class Thread // NOTE: This function may not be called until thread_init has // completed. See thread_suspendAll for more information // on why this might occur. - version( Posix ) + version( OSX ) + { + return sm_this; + } + else version( Posix ) { - // On Posix, pthread_key_t is explicitly used to - // store and access thread reference. This is needed - // to avoid TLS access in signal handlers (malloc deadlock) - // when using shared libraries, see issue 11981. auto t = cast(Thread) pthread_getspecific( sm_this ); return t; } @@ -1237,9 +1236,13 @@ private: // // Local storage // - version( Posix ) + version( OSX ) { - // On Posix, pthread_key_t is explicitly used to + static Thread sm_this; + } + else version( Posix ) + { + // On Posix (excluding OSX), pthread_key_t is explicitly used to // store and access thread reference. This is needed // to avoid TLS access in signal handlers (malloc deadlock) // when using shared libraries, see issue 11981. @@ -1297,12 +1300,12 @@ private: // static void setThis( Thread t ) { - version( Posix ) + version( OSX ) + { + sm_this = t; + } + else version( Posix ) { - // On Posix, pthread_key_t is explicitly used to - // store and access thread reference. This is needed - // to avoid TLS access in signal handlers (malloc deadlock) - // when using shared libraries, see issue 11981. pthread_setspecific( sm_this, cast(void*) t ); } else @@ -1789,10 +1792,6 @@ extern (C) void thread_init() status = sem_init( &suspendCount, 0, 0 ); assert( status == 0 ); - // On Posix, pthread_key_t is explicitly used to - // store and access thread reference. This is needed - // to avoid TLS access in signal handlers (malloc deadlock) - // when using shared libraries, see issue 11981. status = pthread_key_create( &Thread.sm_this, null ); assert( status == 0 ); } @@ -1807,6 +1806,14 @@ extern (C) void thread_init() extern (C) void thread_term() { Thread.termLocks(); + + version( OSX ) + { + } + version( Posix ) + { + pthread_key_delete( Thread.sm_this ); + } } From 4a11d8a260e1ed1447e6a4597055ce2777f19b97 Mon Sep 17 00:00:00 2001 From: Stanislav Blinov Date: Mon, 10 Feb 2014 23:12:10 +0400 Subject: [PATCH 4/4] missing else --- src/core/thread.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/thread.d b/src/core/thread.d index 6730dff8c2..aeaffa0a42 100644 --- a/src/core/thread.d +++ b/src/core/thread.d @@ -1810,7 +1810,7 @@ extern (C) void thread_term() version( OSX ) { } - version( Posix ) + else version( Posix ) { pthread_key_delete( Thread.sm_this ); }