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();
                }
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
 public override void Signal(object state)
 {
     m_signalQueue.Enqueue(state);
     UnsafeMethods.PostQueuedCompletionStatus(m_completionPortHandle, 0, SignalPostCompletionKey, IntPtr.Zero);
 }
Пример #4
0
 internal void PostCompletionStatus(IntPtr overlapped)
 {
     UnsafeMethods.PostQueuedCompletionStatus(m_completionPortHandle, 0, SocketManualCompletionKey, overlapped);
 }
Пример #5
0
        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);
                }
            }
        }