Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix reporting of an async IO timeout error on Windows (SerialPort)
- 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.

Fixes #80079
  • Loading branch information
Koundinya Veluri committed Feb 7, 2023
commit e9ede4832604b2d0493419d6b2522748277cb08e
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ internal static partial class Interop
{
internal static class StatusOptions
{
// See the NT_SUCCESS macro in the Windows SDK, and
// https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
internal static bool NT_SUCCESS(uint ntStatus) => (int)ntStatus >= 0;

// Error codes from ntstatus.h
internal const uint STATUS_SUCCESS = 0x00000000;
internal const uint STATUS_SOME_NOT_MAPPED = 0x00000107;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public static void Invoke(Event e)
// The NtStatus code for the operation is in the InternalLow field
uint ntStatus = (uint)(nint)e.nativeOverlapped->InternalLow;
uint errorCode = Interop.Errors.ERROR_SUCCESS;
if (ntStatus != Interop.StatusOptions.STATUS_SUCCESS)
if (!Interop.StatusOptions.NT_SUCCESS(ntStatus))
{
errorCode = Interop.NtDll.RtlNtStatusToDosError((int)ntStatus);
}
Expand Down