Skip to content

Commit

Permalink
[6.0] Check for pending IO in the portable thread pool's worker threads
Browse files Browse the repository at this point in the history
- Port of dotnet#82245
- When Resource Monitor is attached, some async IO operations are bound to the thread that issued it even though the IO handle is bound to an IOCP. If the thread exits, the async IO operation is aborted. This can lead to hangs or unexpected exceptions.
- Added a check that was missing in the portable thread pool implementation to prevent exiting a worker thread when it has pending IO

Port of fix for dotnet#82207
  • Loading branch information
kouvel committed Mar 8, 2023
1 parent 27d6b41 commit 169ab55
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,9 @@ internal enum ThreadPriority : int

[DllImport(Libraries.Kernel32)]
internal static extern bool SetThreadPriority(SafeWaitHandle hThread, int nPriority);

[DllImport(Libraries.Kernel32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetThreadIOPendingFlag(nint hThread, out BOOL lpIOIsPending);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,9 @@
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.SystemTimeToFileTime.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.SystemTimeToFileTime.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.Threading.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.Threading.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Windows\Kernel32\Interop.TimeZone.cs">
<Link>Common\Interop\Windows\Kernel32\Interop.TimeZone.cs</Link>
</Compile>
Expand Down Expand Up @@ -2301,9 +2304,6 @@
<ItemGroup Condition="'$(FeatureCoreCLR)' != 'true' and '$(TargetsWindows)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Thread.Windows.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\WaitHandle.Windows.cs" />
<Compile Include="$(CommonPath)\Interop\Windows\Kernel32\Interop.Threading.cs">
<Link>Interop\Windows\Kernel32\Interop.Threading.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition="'$(FeatureGenericMath)' == 'true'">
<Compile Include="$(MSBuildThisFileDirectory)System\IAdditionOperators.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Diagnostics.Tracing;

namespace System.Threading
Expand Down Expand Up @@ -101,6 +102,17 @@ private static void WorkerThreadStart()
}
}

// The thread cannot exit if it has IO pending, otherwise the IO may be canceled
bool success =
Interop.Kernel32.GetThreadIOPendingFlag(
Interop.Kernel32.GetCurrentThread(),
out Interop.BOOL isIOPending);
Debug.Assert(success);
if (!success || isIOPending != Interop.BOOL.FALSE)
{
continue;
}

threadAdjustmentLock.Acquire();
try
{
Expand Down

0 comments on commit 169ab55

Please sign in to comment.