@@ -635,6 +635,15 @@ void EEStartupHelper()
635635
636636#ifndef CROSSGEN_COMPILE
637637
638+ // We cache the SystemInfo for anyone to use throughout the life of the EE.
639+ GetSystemInfo (&g_SystemInfo);
640+
641+ // Set callbacks so that LoadStringRC knows which language our
642+ // threads are in so that it can return the proper localized string.
643+ // TODO: This shouldn't rely on the LCID (id), but only the name
644+ SetResourceCultureCallbacks (GetThreadUICultureNames,
645+ GetThreadUICultureId);
646+
638647#ifndef TARGET_UNIX
639648 ::SetConsoleCtrlHandler (DbgCtrlCHandler, TRUE /* add*/ );
640649#endif
@@ -1820,16 +1829,9 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
18201829 {
18211830 case DLL_PROCESS_ATTACH:
18221831 {
1823- // We cache the SystemInfo for anyone to use throughout the
1824- // life of the DLL.
1825- GetSystemInfo (&g_SystemInfo);
1826-
1827- // Set callbacks so that LoadStringRC knows which language our
1828- // threads are in so that it can return the proper localized string.
1829- // TODO: This shouldn't rely on the LCID (id), but only the name
1830- SetResourceCultureCallbacks (GetThreadUICultureNames,
1831- GetThreadUICultureId);
1832-
1832+ g_hmodCoreCLR = pParam->hInst ;
1833+ // Save the module handle.
1834+ g_hThisInst = pParam->hInst ;
18331835 break ;
18341836 }
18351837
@@ -1859,35 +1861,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
18591861 }
18601862 break ;
18611863 }
1862-
1863- case DLL_THREAD_DETACH:
1864- {
1865- // Don't destroy threads here if we're in shutdown (shutdown will
1866- // clean up for us instead).
1867-
1868- Thread* thread = GetThread ();
1869- if (thread)
1870- {
1871- #ifdef FEATURE_COMINTEROP
1872- // reset the CoInitialize state
1873- // so we don't call CoUninitialize during thread detach
1874- thread->ResetCoInitialized ();
1875- #endif // FEATURE_COMINTEROP
1876- // For case where thread calls ExitThread directly, we need to reset the
1877- // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1878- // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1879- if (thread->m_pFrame != FRAME_TOP)
1880- {
1881- #ifdef _DEBUG
1882- thread->m_GCOnTransitionsOK = FALSE ;
1883- #endif
1884- GCX_COOP_NO_DTOR ();
1885- thread->m_pFrame = FRAME_TOP;
1886- GCX_COOP_NO_DTOR_END ();
1887- }
1888- thread->DetachThread (TRUE );
1889- }
1890- }
18911864 }
18921865
18931866 }
@@ -1896,12 +1869,46 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
18961869 }
18971870 PAL_ENDTRY;
18981871
1899- if (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)
1872+ return TRUE ;
1873+ }
1874+
1875+ struct TlsDestructionMonitor
1876+ {
1877+ ~TlsDestructionMonitor ()
19001878 {
1879+ // Don't destroy threads here if we're in shutdown (shutdown will
1880+ // clean up for us instead).
1881+
1882+ Thread* thread = GetThread ();
1883+ if (thread)
1884+ {
1885+ #ifdef FEATURE_COMINTEROP
1886+ // reset the CoInitialize state
1887+ // so we don't call CoUninitialize during thread detach
1888+ thread->ResetCoInitialized ();
1889+ #endif // FEATURE_COMINTEROP
1890+ // For case where thread calls ExitThread directly, we need to reset the
1891+ // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1892+ // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1893+ if (thread->m_pFrame != FRAME_TOP)
1894+ {
1895+ #ifdef _DEBUG
1896+ thread->m_GCOnTransitionsOK = FALSE ;
1897+ #endif
1898+ GCX_COOP_NO_DTOR ();
1899+ thread->m_pFrame = FRAME_TOP;
1900+ GCX_COOP_NO_DTOR_END ();
1901+ }
1902+ thread->DetachThread (TRUE );
1903+ }
1904+
19011905 ThreadDetaching ();
19021906 }
1903- return TRUE ;
1904- }
1907+ };
1908+
1909+ // This thread local object is used to detect thread shutdown. Its destructor
1910+ // is called when a thread is being shut down.
1911+ thread_local TlsDestructionMonitor tls_destructionMonitor;
19051912
19061913#ifdef DEBUGGING_SUPPORTED
19071914//
0 commit comments