@@ -1701,125 +1701,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
1701
1701
1702
1702
#endif // !defined(CORECLR_EMBEDDED)
1703
1703
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
1823
1704
struct TlsDestructionMonitor
1824
1705
{
1825
1706
bool m_activated = false ;
@@ -1833,7 +1714,36 @@ struct TlsDestructionMonitor
1833
1714
{
1834
1715
if (m_activated)
1835
1716
{
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 ();
1837
1747
}
1838
1748
}
1839
1749
};
@@ -1847,8 +1757,6 @@ void EnsureTlsDestructionMonitor()
1847
1757
tls_destructionMonitor.Activate ();
1848
1758
}
1849
1759
1850
- #endif
1851
-
1852
1760
#ifdef DEBUGGING_SUPPORTED
1853
1761
//
1854
1762
// InitializeDebugger initialized the Runtime-side COM+ Debugging Services
0 commit comments