Skip to content

Commit 593ca95

Browse files
authored
Revert "Use FLS detach as thread termination notification on windows. (#110589)"
This reverts commit 69d8076.
1 parent 8edcc31 commit 593ca95

File tree

4 files changed

+31
-140
lines changed

4 files changed

+31
-140
lines changed

src/coreclr/nativeaot/Runtime/threadstore.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ void ThreadStore::DetachCurrentThread()
162162
}
163163

164164
// Unregister from OS notifications
165-
// This can return false if a thread did not register for OS notification.
165+
// This can return false if detach notification is spurious and does not belong to this thread.
166166
if (!PalDetachThread(pDetachingThread))
167167
{
168168
return;

src/coreclr/vm/ceemain.cpp

+30-122
Original file line numberDiff line numberDiff line change
@@ -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
18231704
struct 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

src/coreclr/vm/ceemain.h

-4
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,6 @@ void ForceEEShutdown(ShutdownCompleteAction sca = SCA_ExitProcessWhenShutdownCom
4646
void ThreadDetaching();
4747

4848
void EnsureTlsDestructionMonitor();
49-
#ifdef TARGET_WINDOWS
50-
void InitFlsSlot();
51-
void OsDetachThread(void* thread);
52-
#endif
5349

5450
void SetLatchedExitCode (INT32 code);
5551
INT32 GetLatchedExitCode (void);

src/coreclr/vm/threads.cpp

-13
Original file line numberDiff line numberDiff line change
@@ -353,22 +353,13 @@ void SetThread(Thread* t)
353353
{
354354
LIMITED_METHOD_CONTRACT
355355

356-
Thread* origThread = gCurrentThreadInfo.m_pThread;
357356
gCurrentThreadInfo.m_pThread = t;
358357
if (t != NULL)
359358
{
360359
InitializeCurrentThreadsStaticData(t);
361360
EnsureTlsDestructionMonitor();
362361
t->InitRuntimeThreadLocals();
363362
}
364-
#ifdef TARGET_WINDOWS
365-
else if (origThread != NULL)
366-
{
367-
// Unregister from OS notifications
368-
// This can return false if a thread did not register for OS notification.
369-
OsDetachThread(origThread);
370-
}
371-
#endif
372363

373364
// Clear or set the app domain to the one domain based on if the thread is being nulled out or set
374365
gCurrentThreadInfo.m_pAppDomain = t == NULL ? NULL : AppDomain::GetCurrentDomain();
@@ -1048,10 +1039,6 @@ void InitThreadManager()
10481039
}
10491040
CONTRACTL_END;
10501041

1051-
#ifdef TARGET_WINDOWS
1052-
InitFlsSlot();
1053-
#endif
1054-
10551042
// All patched helpers should fit into one page.
10561043
// If you hit this assert on retail build, there is most likely problem with BBT script.
10571044
_ASSERTE_ALL_BUILDS((BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart > (ptrdiff_t)0);

0 commit comments

Comments
 (0)