@@ -1701,125 +1701,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
17011701
17021702#endif // !defined(CORECLR_EMBEDDED)
17031703
1704- static void RuntimeThreadShutdown (void * thread)
1705- {
1706- Thread* pThread = (Thread*)thread;
1707- _ASSERTE (pThread == GetThreadNULLOk ());
1708-
1709- if (pThread)
1710- {
1711- #ifdef FEATURE_COMINTEROP
1712- // reset the CoInitialize state
1713- // so we don't call CoUninitialize during thread detach
1714- pThread->ResetCoInitialized ();
1715- #endif // FEATURE_COMINTEROP
1716- // For case where thread calls ExitThread directly, we need to reset the
1717- // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1718- // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1719- if (pThread->m_pFrame != FRAME_TOP)
1720- {
1721- #ifdef _DEBUG
1722- pThread->m_GCOnTransitionsOK = FALSE ;
1723- #endif
1724- GCX_COOP_NO_DTOR ();
1725- pThread->m_pFrame = FRAME_TOP;
1726- GCX_COOP_NO_DTOR_END ();
1727- }
1728-
1729- pThread->DetachThread (TRUE );
1730- }
1731- else
1732- {
1733- // Since we don't actually cleanup the TLS data along this path, verify that it is already cleaned up
1734- AssertThreadStaticDataFreed ();
1735- }
1736-
1737- ThreadDetaching ();
1738- }
1739-
1740- #ifdef TARGET_WINDOWS
1741-
1742- // Index for the fiber local storage of the attached thread pointer
1743- static uint32_t g_flsIndex = FLS_OUT_OF_INDEXES;
1744-
1745- // This is called when each *fiber* is destroyed. When the home fiber of a thread is destroyed,
1746- // it means that the thread itself is destroyed.
1747- // Since we receive that notification outside of the Loader Lock, it allows us to safely acquire
1748- // the ThreadStore lock in the RuntimeThreadShutdown.
1749- static void __stdcall FiberDetachCallback (void * lpFlsData)
1750- {
1751- ASSERT (g_flsIndex != FLS_OUT_OF_INDEXES);
1752- ASSERT (lpFlsData == FlsGetValue (g_flsIndex));
1753-
1754- if (lpFlsData != NULL )
1755- {
1756- // The current fiber is the home fiber of a thread, so the thread is shutting down
1757- RuntimeThreadShutdown (lpFlsData);
1758- }
1759- }
1760-
1761- void InitFlsSlot ()
1762- {
1763- // We use fiber detach callbacks to run our thread shutdown code because the fiber detach
1764- // callback is made without the OS loader lock
1765- g_flsIndex = FlsAlloc (FiberDetachCallback);
1766- if (g_flsIndex == FLS_OUT_OF_INDEXES)
1767- {
1768- COMPlusThrowWin32 ();
1769- }
1770- }
1771-
1772- // Register the thread with OS to be notified when thread is about to be destroyed
1773- // It fails fast if a different thread was already registered with the current fiber.
1774- // Parameters:
1775- // thread - thread to attach
1776- static void OsAttachThread (void * thread)
1777- {
1778- void * threadFromCurrentFiber = FlsGetValue (g_flsIndex);
1779-
1780- if (threadFromCurrentFiber != NULL )
1781- {
1782- _ASSERTE_ALL_BUILDS (!" Multiple threads encountered from a single fiber" );
1783- }
1784-
1785- // Associate the current fiber with the current thread. This makes the current fiber the thread's "home"
1786- // fiber. This fiber is the only fiber allowed to execute managed code on this thread. When this fiber
1787- // is destroyed, we consider the thread to be destroyed.
1788- FlsSetValue (g_flsIndex, thread);
1789- }
1790-
1791- // Detach thread from OS notifications.
1792- // It fails fast if some other thread value was attached to the current fiber.
1793- // Parameters:
1794- // thread - thread to detach
1795- // Return:
1796- // true if the thread was detached, false if there was no attached thread
1797- void OsDetachThread (void * thread)
1798- {
1799- ASSERT (g_flsIndex != FLS_OUT_OF_INDEXES);
1800- void * threadFromCurrentFiber = FlsGetValue (g_flsIndex);
1801-
1802- if (threadFromCurrentFiber == NULL )
1803- {
1804- // we've seen this thread, but not this fiber. It must be a "foreign" fiber that was
1805- // borrowing this thread.
1806- return ;
1807- }
1808-
1809- if (threadFromCurrentFiber != thread)
1810- {
1811- _ASSERTE_ALL_BUILDS (!" Detaching a thread from the wrong fiber" );
1812- }
1813-
1814- FlsSetValue (g_flsIndex, NULL );
1815- }
1816-
1817- void EnsureTlsDestructionMonitor ()
1818- {
1819- OsAttachThread (GetThread ());
1820- }
1821-
1822- #else
18231704struct TlsDestructionMonitor
18241705{
18251706 bool m_activated = false ;
@@ -1833,7 +1714,36 @@ struct TlsDestructionMonitor
18331714 {
18341715 if (m_activated)
18351716 {
1836- RuntimeThreadShutdown (GetThreadNULLOk ());
1717+ Thread* thread = GetThreadNULLOk ();
1718+ if (thread)
1719+ {
1720+ #ifdef FEATURE_COMINTEROP
1721+ // reset the CoInitialize state
1722+ // so we don't call CoUninitialize during thread detach
1723+ thread->ResetCoInitialized ();
1724+ #endif // FEATURE_COMINTEROP
1725+ // For case where thread calls ExitThread directly, we need to reset the
1726+ // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
1727+ // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
1728+ if (thread->m_pFrame != FRAME_TOP)
1729+ {
1730+ #ifdef _DEBUG
1731+ thread->m_GCOnTransitionsOK = FALSE ;
1732+ #endif
1733+ GCX_COOP_NO_DTOR ();
1734+ thread->m_pFrame = FRAME_TOP;
1735+ GCX_COOP_NO_DTOR_END ();
1736+ }
1737+
1738+ thread->DetachThread (TRUE );
1739+ }
1740+ else
1741+ {
1742+ // Since we don't actually cleanup the TLS data along this path, verify that it is already cleaned up
1743+ AssertThreadStaticDataFreed ();
1744+ }
1745+
1746+ ThreadDetaching ();
18371747 }
18381748 }
18391749};
@@ -1847,8 +1757,6 @@ void EnsureTlsDestructionMonitor()
18471757 tls_destructionMonitor.Activate ();
18481758}
18491759
1850- #endif
1851-
18521760#ifdef DEBUGGING_SUPPORTED
18531761//
18541762// InitializeDebugger initialized the Runtime-side COM+ Debugging Services
0 commit comments