private void Dispose(bool disposing) { if (!m_disposed) { m_disposed = true; m_inOverlapped.Dispose(); m_outOverlapped.Dispose(); // for Windows XP #if NETSTANDARD1_3 UnsafeMethods.CancelIoEx(Handle, IntPtr.Zero); #else if (Environment.OSVersion.Version.Major == 5) { UnsafeMethods.CancelIo(Handle); } else { UnsafeMethods.CancelIoEx(Handle, IntPtr.Zero); } #endif int error = UnsafeMethods.closesocket(Handle); if (error != 0) { error = Marshal.GetLastWin32Error(); } if (m_remoteAddress != null) { m_remoteAddress.Dispose(); m_remoteAddress = null; } if (m_boundAddress != null) { m_boundAddress.Dispose(); m_boundAddress = null; } if (m_sendPinnedBuffer != null) { m_sendPinnedBuffer.Dispose(); m_sendPinnedBuffer = null; } if (m_receivePinnedBuffer != null) { m_receivePinnedBuffer.Dispose(); m_receivePinnedBuffer = null; } if (m_acceptSocketBufferAddress != IntPtr.Zero) { Marshal.FreeHGlobal(m_acceptSocketBufferAddress); } if (m_acceptSocket != null) { m_acceptSocket.Dispose(); } } }
public override bool GetMultipleQueuedCompletionStatus(int timeout, CompletionStatus[] completionStatuses, out int removed) { // Windows XP Has NO GetQueuedCompletionStatusEx // so we need dequeue IOPC one by one #if NETSTANDARD1_3 if (false) { } #else if (false) { removed = 0; CompletionStatus completeStatus; bool result = GetQueuedCompletionStatus(timeout, out completeStatus); if (result) { completionStatuses[0] = completeStatus; removed = 1; } return(result); } #endif else { if (m_overlappedEntries == null || m_overlappedEntries.Length < completionStatuses.Length) { if (m_overlappedEntries != null) { m_overlappedEntriesHandle.Free(); } m_overlappedEntries = new OverlappedEntry[completionStatuses.Length]; m_overlappedEntriesHandle = GCHandle.Alloc(m_overlappedEntries, GCHandleType.Pinned); m_overlappedEntriesAddress = Marshal.UnsafeAddrOfPinnedArrayElement(m_overlappedEntries, 0); } bool result = UnsafeMethods.GetQueuedCompletionStatusEx(m_completionPortHandle, m_overlappedEntriesAddress, completionStatuses.Length, out removed, timeout, false); if (!result) { int error = Marshal.GetLastWin32Error(); if (error == WaitTimeoutError) { removed = 0; return(false); } throw new Win32Exception(error); } for (int i = 0; i < removed; i++) { HandleCompletionStatus(out completionStatuses[i], m_overlappedEntries[i].Overlapped, m_overlappedEntries[i].CompletionKey, m_overlappedEntries[i].BytesTransferred); } } return(true); }
public override void Signal(object state) { m_signalQueue.Enqueue(state); UnsafeMethods.PostQueuedCompletionStatus(m_completionPortHandle, 0, SignalPostCompletionKey, IntPtr.Zero); }
internal void PostCompletionStatus(IntPtr overlapped) { UnsafeMethods.PostQueuedCompletionStatus(m_completionPortHandle, 0, SocketManualCompletionKey, overlapped); }
private void HandleCompletionStatus(out CompletionStatus completionStatus, IntPtr overlappedAddress, IntPtr completionKey, int bytesTransferred) { if (completionKey.Equals(SignalPostCompletionKey)) { object state; m_signalQueue.TryDequeue(out state); completionStatus = new CompletionStatus(null, state, OperationType.Signal, SocketError.Success, 0); } else { var overlapped = Overlapped.CompleteOperation(overlappedAddress); if (completionKey.Equals(SocketCompletionKey)) { // if the overlapped ntstatus is zero we assume success and don't call get overlapped result for optimization if (overlapped.Success) { SocketError socketError = SocketError.Success; try { if (overlapped.OperationType == OperationType.Accept) { overlapped.AsyncSocket.UpdateAccept(); } else if (overlapped.OperationType == OperationType.Connect) { overlapped.AsyncSocket.UpdateConnect(); } } catch (SocketException ex) { socketError = ex.SocketErrorCode; } completionStatus = new CompletionStatus(overlapped.AsyncSocket, overlapped.State, overlapped.OperationType, socketError, bytesTransferred); } else { SocketError socketError = SocketError.Success; SocketFlags socketFlags; bool operationSucceed = UnsafeMethods.WSAGetOverlappedResult(overlapped.AsyncSocket.Handle, overlappedAddress, out bytesTransferred, false, out socketFlags); if (!operationSucceed) { socketError = (SocketError)Marshal.GetLastWin32Error(); } completionStatus = new CompletionStatus(overlapped.AsyncSocket, overlapped.State, overlapped.OperationType, socketError, bytesTransferred); } } else { completionStatus = new CompletionStatus(overlapped.AsyncSocket, overlapped.State, overlapped.OperationType, SocketError.Success, 0); } } }