private unsafe void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped)
{
#if DEBUG
DebugThreadTracking.SetThreadSource(ThreadKinds.CompletionPort);
using (DebugThreadTracking.SetThreadKind(ThreadKinds.System))
{
if (NetEventSource.IsEnabled) NetEventSource.Enter(this, $"errorCode:{errorCode}, numBytes:{numBytes}, overlapped:{(IntPtr)nativeOverlapped}");
#endif
SocketFlags socketFlags = SocketFlags.None;
SocketError socketError = (SocketError)errorCode;
// This is the same NativeOverlapped* as we already have a SafeHandle for, re-use the original.
Debug.Assert((IntPtr)nativeOverlapped == _ptrNativeOverlapped.DangerousGetHandle(), "Handle mismatch");
if (socketError == SocketError.Success)
{
FinishOperationSuccess(socketError, (int)numBytes, socketFlags);
}
else
{
if (socketError != SocketError.OperationAborted)
{
if (_currentSocket.CleanedUp)
{
socketError = SocketError.OperationAborted;
}
else
{
try
{
// The Async IO completed with a failure.
// here we need to call WSAGetOverlappedResult() just so Marshal.GetLastWin32Error() will return the correct error.
bool success = Interop.Winsock.WSAGetOverlappedResult(
_currentSocket.SafeHandle,
_ptrNativeOverlapped,
out numBytes,
false,
out socketFlags);
socketError = SocketPal.GetLastSocketError();
}
catch
{
// _currentSocket.CleanedUp check above does not always work since this code is subject to race conditions.
socketError = SocketError.OperationAborted;
}
}
}
FinishOperationAsyncFailure(socketError, (int)numBytes, socketFlags);
}
#if DEBUG
if (NetEventSource.IsEnabled) NetEventSource.Exit(this);
}
#endif
}
}