diff --git a/src/core/thread.d b/src/core/thread.d index 8b103ee03f..aeaffa0a42 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,7 +1065,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( OSX ) + { + return sm_this; + } + else version( Posix ) + { + auto t = cast(Thread) pthread_getspecific( sm_this ); + return t; + } + else + { + return sm_this; + } } @@ -1225,7 +1236,22 @@ private: // // Local storage // - static Thread sm_this; + version( OSX ) + { + 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. + __gshared pthread_key_t sm_this; + } + else + { + static Thread sm_this; + } // @@ -1274,7 +1300,18 @@ private: // static void setThis( Thread t ) { - sm_this = t; + version( OSX ) + { + sm_this = t; + } + else version( Posix ) + { + pthread_setspecific( sm_this, cast(void*) t ); + } + else + { + sm_this = t; + } } @@ -1754,6 +1791,9 @@ extern (C) void thread_init() status = sem_init( &suspendCount, 0, 0 ); assert( status == 0 ); + + status = pthread_key_create( &Thread.sm_this, null ); + assert( status == 0 ); } Thread.sm_main = thread_attachThis(); } @@ -1766,6 +1806,14 @@ extern (C) void thread_init() extern (C) void thread_term() { Thread.termLocks(); + + version( OSX ) + { + } + else version( Posix ) + { + pthread_key_delete( Thread.sm_this ); + } }