Skip to content

Commit 75979eb

Browse files
authored
[7.0] Fix reporting of an async IO timeout error on Windows (SerialPort) (#81745)
- Port of #81744 - When an async `SerialPort` IO operation times out, it reports the timeout in the IO completion with an `NTSTATUS` value of `WAIT_TIMEOUT` (258) - In the thread pool when using `GetQueuedCompletionStatusEx`, the `NTSTATUS` value was being checked against `STATUS_SUCCESS` to determine success, so the `WAIT_TIMEOUT` was reported as an error. This leads to a different exception being thrown, compared to before when `GetQueuedCompletionStatus` was used. - Fixed to use similar logic to the SDK's `NT_SUCCESS` macro, which treats the `WAIT_TIMEOUT` value as a success, which is similar to what `GetQueuedCompletionStatus` does - There are already tests that verify this behavior in `System.IO.Ports` tests, though [they are currently disabled](https://github.com/dotnet/runtime/blob/b39d6a6eb44860746e91e5ce4f585beff33d1f63/src/libraries/System.IO.Ports/tests/Support/TCSupport.cs#L108-L118) due to instabilities. I have verified locally that the relevant failures are fixed and that there are no new failures in those tests. Relevant to #80079
1 parent 2964613 commit 75979eb

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

src/libraries/Common/src/Interop/Windows/NtDll/Interop.NtStatus.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ internal static partial class Interop
55
{
66
internal static class StatusOptions
77
{
8+
// See the NT_SUCCESS macro in the Windows SDK, and
9+
// https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
10+
internal static bool NT_SUCCESS(uint ntStatus) => (int)ntStatus >= 0;
11+
812
// Error codes from ntstatus.h
913
internal const uint STATUS_SUCCESS = 0x00000000;
1014
internal const uint STATUS_SOME_NOT_MAPPED = 0x00000107;

src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.IO.Windows.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ public static void Invoke(Event e)
257257
// The NtStatus code for the operation is in the InternalLow field
258258
uint ntStatus = (uint)(nint)e.nativeOverlapped->InternalLow;
259259
uint errorCode = Interop.Errors.ERROR_SUCCESS;
260-
if (ntStatus != Interop.StatusOptions.STATUS_SUCCESS)
260+
if (!Interop.StatusOptions.NT_SUCCESS(ntStatus))
261261
{
262262
errorCode = Interop.NtDll.RtlNtStatusToDosError((int)ntStatus);
263263
}

0 commit comments

Comments
 (0)