private unsafe void PrepareIOCPOperation()
{
Debug.Assert(_currentSocket != null, "_currentSocket is null");
Debug.Assert(_currentSocket.SafeHandle != null, "_currentSocket.SafeHandle is null");
Debug.Assert(!_currentSocket.SafeHandle.IsInvalid, "_currentSocket.SafeHandle is invalid");
ThreadPoolBoundHandle boundHandle = _currentSocket.SafeHandle.GetOrAllocateThreadPoolBoundHandle();
NativeOverlapped* overlapped = null;
if (_preAllocatedOverlapped != null)
{
overlapped = boundHandle.AllocateNativeOverlapped(_preAllocatedOverlapped);
if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"boundHandle:{boundHandle}, PreAllocatedOverlapped:{_preAllocatedOverlapped}, Returned:{(IntPtr)overlapped}");
}
else
{
overlapped = boundHandle.AllocateNativeOverlapped(CompletionPortCallback, this, null);
if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"boundHandle:{boundHandle}, AllocateNativeOverlapped(pinData=null), Returned:{(IntPtr)overlapped}");
}
Debug.Assert(overlapped != null, "NativeOverlapped is null.");
// If we already have a SafeNativeOverlapped SafeHandle and it's associated with the same
// socket (due to the last operation that used this SocketAsyncEventArgs using the same socket),
// then we can reuse the same SafeHandle object. Otherwise, this is either the first operation
// or the last operation was with a different socket, so create a new SafeHandle.
if (_ptrNativeOverlapped?.SocketHandle == _currentSocket.SafeHandle)
{
_ptrNativeOverlapped.ReplaceHandle(overlapped);
}
else
{
_ptrNativeOverlapped?.Dispose();
_ptrNativeOverlapped = new SafeNativeOverlapped(_currentSocket.SafeHandle, overlapped);
}
}