@@ -452,6 +452,12 @@ class Thread : ThreadBase
452452 onThreadError( " Error initializing thread stack size" );
453453 }
454454
455+ version (Shared)
456+ {
457+ auto ps = cast (void ** ).malloc(2 * size_t .sizeof);
458+ if (ps is null ) onOutOfMemoryError();
459+ }
460+
455461 version (Windows )
456462 {
457463 // NOTE: If a thread is just executing DllMain()
@@ -464,7 +470,11 @@ class Thread : ThreadBase
464470 // Solution: Create the thread in suspended state and then
465471 // add and resume it with slock acquired
466472 assert (m_sz <= uint .max, " m_sz must be less than or equal to uint.max" );
467- m_hndl = cast (HANDLE ) _beginthreadex( null , cast (uint ) m_sz, &thread_entryPoint, cast (void * ) this , CREATE_SUSPENDED , &m_addr );
473+ version (Shared)
474+ auto threadArg = cast (void * ) ps;
475+ else
476+ auto threadArg = cast (void * ) this ;
477+ m_hndl = cast (HANDLE ) _beginthreadex( null , cast (uint ) m_sz, &thread_entryPoint, threadArg, CREATE_SUSPENDED , &m_addr );
468478 if ( cast (size_t ) m_hndl == 0 )
469479 onThreadError( " Error creating thread" );
470480 }
@@ -475,44 +485,63 @@ class Thread : ThreadBase
475485 ++ nAboutToStart;
476486 pAboutToStart = cast (ThreadBase* )realloc(pAboutToStart, Thread .sizeof * nAboutToStart);
477487 pAboutToStart[nAboutToStart - 1 ] = this ;
478- version (Windows )
479- {
480- if ( ResumeThread( m_hndl ) == - 1 )
481- onThreadError( " Error resuming thread" );
482- }
483- else version (Posix )
488+
489+ version (Posix )
484490 {
485491 // NOTE: This is also set to true by thread_entryPoint, but set it
486492 // here as well so the calling thread will see the isRunning
487493 // state immediately.
488494 atomicStore! (MemoryOrder.raw)(m_isRunning, true );
489495 scope ( failure ) atomicStore! (MemoryOrder.raw)(m_isRunning, false );
496+ }
490497
491- version (Shared)
492- {
493- auto libs = externDFunc! (" rt.sections_elf_shared.pinLoadedLibraries" ,
494- void * function () @nogc nothrow )();
498+ version (Shared)
499+ {
500+ auto libs = externDFunc! (" rt.sections_elf_shared.pinLoadedLibraries" ,
501+ void * function () @nogc nothrow )();
502+
503+ ps[0 ] = cast (void * )this ;
504+ ps[1 ] = cast (void * )libs;
495505
496- auto ps = cast (void ** ).malloc(2 * size_t .sizeof);
497- if (ps is null ) onOutOfMemoryError();
498- ps[0 ] = cast (void * )this ;
499- ps[1 ] = cast (void * )libs;
506+ version (Windows )
507+ {
508+ if ( ResumeThread( m_hndl ) == - 1 )
509+ {
510+ externDFunc! (" rt.sections_elf_shared.unpinLoadedLibraries" ,
511+ void function (void * ) @nogc nothrow )(libs);
512+ .free(ps);
513+ onThreadError( " Error resuming thread" );
514+ }
515+ }
516+ else version (Posix )
517+ {
500518 if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 )
501519 {
502520 externDFunc! (" rt.sections_elf_shared.unpinLoadedLibraries" ,
503- void function (void * ) @nogc nothrow )(libs);
521+ void function (void * ) @nogc nothrow )(libs);
504522 .free(ps);
505523 onThreadError( " Error creating thread" );
506524 }
525+ if ( pthread_attr_destroy( &attr ) != 0 )
526+ onThreadError( " Error destroying thread attributes" );
507527 }
508- else
528+ }
529+ else
530+ {
531+ version (Windows )
532+ {
533+ if ( ResumeThread( m_hndl ) == - 1 )
534+ onThreadError( " Error resuming thread" );
535+ }
536+ else version (Posix )
509537 {
510538 if ( pthread_create( &m_addr, &attr, &thread_entryPoint, cast (void * ) this ) != 0 )
511539 onThreadError( " Error creating thread" );
540+ if ( pthread_attr_destroy( &attr ) != 0 )
541+ onThreadError( " Error destroying thread attributes" );
512542 }
513- if ( pthread_attr_destroy( &attr ) != 0 )
514- onThreadError( " Error destroying thread attributes" );
515543 }
544+
516545 version (Darwin)
517546 {
518547 m_tmach = pthread_mach_thread_np( m_addr );
@@ -2173,9 +2202,26 @@ version (Windows)
21732202 //
21742203 extern (Windows ) uint thread_entryPoint( void * arg ) nothrow
21752204 {
2176- Thread obj = cast (Thread ) arg;
2205+ version (Shared)
2206+ {
2207+ Thread obj = cast (Thread )(cast (void ** )arg)[0 ];
2208+ auto loadedLibraries = (cast (void ** )arg)[1 ];
2209+ .free(arg);
2210+ }
2211+ else
2212+ {
2213+ Thread obj = cast (Thread )arg;
2214+ }
21772215 assert ( obj );
21782216
2217+ // loadedLibraries need to be inherited from parent thread
2218+ // before initilizing GC for TLS (rt_tlsgc_init)
2219+ version (Shared)
2220+ {
2221+ externDFunc! (" rt.sections_elf_shared.inheritLoadedLibraries" ,
2222+ void function (void * ) @nogc nothrow )(loadedLibraries);
2223+ }
2224+
21792225 obj.initDataStorage();
21802226
21812227 Thread .setThis(obj);
@@ -2219,6 +2265,11 @@ version (Windows)
22192265 append( t );
22202266 }
22212267 rt_moduleTlsDtor();
2268+ version (Shared)
2269+ {
2270+ externDFunc! (" rt.sections_elf_shared.cleanupLoadedLibraries" ,
2271+ void function () @nogc nothrow )();
2272+ }
22222273 }
22232274 catch ( Throwable t )
22242275 {
0 commit comments