Skip to content

Commit 4a27a27

Browse files
committed
Cleanup on the finalizer thread when a thread is detached, not when the managed thread object is finalized.
1 parent 2b610bf commit 4a27a27

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,6 @@ private void Initialize()
178178
/// <summary>Clean up the thread when it goes away.</summary>
179179
~Thread()
180180
{
181-
// During the actual thread shutdown,
182-
// it may not be practical for us to run enough managed code to clean up
183-
// any managed code that needs to know when a thread exits.
184-
// Instead, run that clean up here when the thread object is finalized
185-
// (which is definitely after the thread has exited)
186-
OnThreadExiting();
187-
188181
// Do any additional finalization that's required on the unmanaged side.
189182
InternalFinalize();
190183
}

src/coreclr/vm/corelib.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,7 @@ DEFINE_CLASS(DIRECTONTHREADLOCALDATA, Threading, Thread+DirectOnThreadLocalData)
969969
DEFINE_CLASS(THREAD, Threading, Thread)
970970
DEFINE_METHOD(THREAD, START_CALLBACK, StartCallback, IM_RetVoid)
971971
DEFINE_METHOD(THREAD, POLLGC, PollGC, NoSig)
972+
DEFINE_METHOD(THREAD, ON_THREAD_EXITING, OnThreadExiting, IM_RetVoid)
972973

973974
#ifdef FEATURE_OBJCMARSHAL
974975
DEFINE_CLASS(AUTORELEASEPOOL, Threading, AutoreleasePool)

src/coreclr/vm/threads.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2575,7 +2575,8 @@ void Thread::CoUninitialize()
25752575
void Thread::CleanupDetachedThreads()
25762576
{
25772577
CONTRACTL {
2578-
NOTHROW;
2578+
THROWS;
2579+
MODE_COOPERATIVE;
25792580
GC_TRIGGERS;
25802581
}
25812582
CONTRACTL_END;
@@ -2596,6 +2597,20 @@ void Thread::CleanupDetachedThreads()
25962597
{
25972598
STRESS_LOG1(LF_SYNC, LL_INFO1000, "T::CDT - detaching thread 0x%p\n", thread);
25982599

2600+
if (!thread->IsGCSpecial())
2601+
{
2602+
GCX_COOP();
2603+
// During the actual thread shutdown,
2604+
// it may not be practical for us to run enough managed code to clean up
2605+
// any managed code that needs to know when a thread exits.
2606+
// Instead, run that clean up here when the thread object is finalized
2607+
// (which is definitely after the thread has exited)
2608+
PREPARE_NONVIRTUAL_CALLSITE(METHOD__THREAD__ON_THREAD_EXITING);
2609+
DECLARE_ARGHOLDER_ARRAY(args, 1);
2610+
args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(thread->GetExposedObject());
2611+
CALL_MANAGED_METHOD_NORET(args);
2612+
}
2613+
25992614
// Unmark that the thread is detached while we have the
26002615
// thread store lock. This will ensure that no other
26012616
// thread will race in here and try to delete it, too.

0 commit comments

Comments
 (0)