예제 #1
0
        public static unsafe SocketError ReceiveAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            // Set up asyncResult for overlapped WSARecv.
            asyncResult.SetUnmanagedStructures(buffer, offset, count, null, false /* don't pin null RemoteEP*/);
            try
            {
                // This can throw ObjectDisposedException.
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSARecv(
                    handle,
                    ref asyncResult._singleBuffer,
                    1,
                    out bytesTransferred,
                    ref socketFlags,
                    asyncResult.OverlappedHandle,
                    IntPtr.Zero);

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #2
0
        public static unsafe SocketError SendAsync(SafeCloseSocket handle, IList <ArraySegment <byte> > buffers, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            // Set up asyncResult for overlapped WSASend.
            asyncResult.SetUnmanagedStructures(buffers);
            try
            {
                // This can throw ObjectDisposedException.
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSASend(
                    handle,
                    asyncResult._wsaBuffers,
                    asyncResult._wsaBuffers.Length,
                    out bytesTransferred,
                    socketFlags,
                    asyncResult.OverlappedHandle,
                    IntPtr.Zero);

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #3
0
        public static unsafe SocketError SendToAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult)
        {
            // Set up asyncResult for overlapped WSASendTo.
            asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, false /* don't pin RemoteEP*/);
            try
            {
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSASendTo(
                    handle,
                    ref asyncResult._singleBuffer,
                    1, // There is only ever 1 buffer being sent.
                    out bytesTransferred,
                    socketFlags,
                    asyncResult.GetSocketAddressPtr(),
                    asyncResult.SocketAddress.Size,
                    asyncResult.OverlappedHandle,
                    IntPtr.Zero);

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #4
0
        public static unsafe SocketError ReceiveAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            // Set up asyncResult for overlapped WSARecv.
            asyncResult.SetUnmanagedStructures(buffer, offset, count, null);
            try
            {
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSARecv(
                    handle.DangerousGetHandle(), // to minimize chances of handle recycling from misuse, this should use DangerousAddRef/Release, but it adds too much overhead
                    ref asyncResult._singleBuffer,
                    1,
                    out bytesTransferred,
                    ref socketFlags,
                    asyncResult.DangerousOverlappedPointer, // SafeHandle was just created in SetUnmanagedStructures
                    IntPtr.Zero);
                GC.KeepAlive(handle);                       // small extra safe guard against handle getting collected/finalized while P/Invoke in progress

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #5
0
        public static unsafe SocketError ReceiveFromAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult)
        {
            // Set up asyncResult for overlapped WSARecvFrom.
            asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, true);
            try
            {
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSARecvFrom(
                    handle,
                    ref asyncResult._singleBuffer,
                    1,
                    out bytesTransferred,
                    ref socketFlags,
                    asyncResult.GetSocketAddressPtr(),
                    asyncResult.GetSocketAddressSizePtr(),
                    asyncResult.OverlappedHandle,
                    IntPtr.Zero);

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #6
0
        public static unsafe SocketError SendAsync(SafeCloseSocket handle, IList <ArraySegment <byte> > buffers, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            // Set up asyncResult for overlapped WSASend.
            asyncResult.SetUnmanagedStructures(buffers);
            try
            {
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSASend(
                    handle.DangerousGetHandle(), // to minimize chances of handle recycling from misuse, this should use DangerousAddRef/Release, but it adds too much overhead
                    asyncResult._wsaBuffers,
                    asyncResult._wsaBuffers.Length,
                    out bytesTransferred,
                    socketFlags,
                    asyncResult.DangerousOverlappedPointer, // SafeHandle was just created in SetUnmanagedStructures
                    IntPtr.Zero);
                GC.KeepAlive(handle);                       // small extra safe guard against handle getting collected/finalized while P/Invoke in progress

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #7
0
        public static unsafe SocketError SendAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            // Set up unmanaged structures for overlapped WSASend.
            asyncResult.SetUnmanagedStructures(buffer, offset, count, null);
            try
            {
                // This can throw ObjectDisposedException.
                int         bytesTransferred;
                SocketError errorCode = Interop.Winsock.WSASend(
                    handle,
                    ref asyncResult._singleBuffer,
                    1, // There is only ever 1 buffer being sent.
                    out bytesTransferred,
                    socketFlags,
                    asyncResult.OverlappedHandle,
                    IntPtr.Zero);

                return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred));
            }
            catch
            {
                asyncResult.ReleaseUnmanagedStructures();
                throw;
            }
        }
예제 #8
0
        //
        // The overlapped function called (either by the thread pool or the socket)
        // when IO completes. (only called on Win9x)
        //
        internal void OverlappedCallback(object stateObject, bool Signaled)
        {
            OverlappedAsyncResult asyncResult = (OverlappedAsyncResult)stateObject;

            //
            // See if it's been completed already. If it has, we've been called
            // directly, so all we have to do it call the user's callback.
            //

            if (!asyncResult.IsCompleted)
            {
                //
                // the IO completed asynchronously, see if there was a failure:
                // We need to call WSAGetOverlappedResult to find out the errorCode,
                // of this IO, but we will, instead, look into the overlapped
                // structure to improve performance avoiding a PInvoke call.
                // the following code avoids a very expensive call to
                // the Win32 native WSAGetOverlappedResult() function.
                //
                asyncResult.Result = Win32.HackedGetOverlappedResult(asyncResult.m_UnmanagedBlob);

                //
                // this will release the unmanaged pin handles and unmanaged overlapped ptr
                //
                asyncResult.ReleaseUnmanagedStructures();
            }

            //
            // complete the IO and call the user's callback.
            //
            asyncResult.InvokeCallback(false);
        } // OverlappedCallback()
        //
        // This method will be called by us when the IO completes synchronously and
        // by the ThreadPool when the IO completes asynchronously. (only called on WinNT)
        //

        private unsafe static void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped)
        {
            //
            // Create an Overlapped object out of the native pointer we're provided with.
            // (this will NOT free the unmanaged memory in the native overlapped structure)
            //
            Overlapped callbackOverlapped = Overlapped.Unpack(nativeOverlapped);
            //
            // The Overlapped object contains the SocketAsyncResult object
            // that was used for the IO that just completed.
            //
            OverlappedAsyncResult asyncResult = (OverlappedAsyncResult)callbackOverlapped.AsyncResult;

            GlobalLog.Assert(!asyncResult.IsCompleted, "OverlappedAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::CompletionPortCallback() asyncResult.IsCompleted", "");

#if COMNET_PERFLOGGING
            long timer = 0;
            Microsoft.Win32.SafeNativeMethods.QueryPerformanceCounter(out timer);
            Console.WriteLine(timer + ", CompletionPortCallback(" + asyncResult.GetHashCode() + " 0x" + ((long)nativeOverlapped).ToString("X8") + ") numBytes:" + numBytes);
#endif // #if COMNET_PERFLOGGING

            GlobalLog.Print("OverlappedAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::CompletionPortCallback" +
                            " errorCode:" + errorCode.ToString() +
                            " numBytes:" + numBytes.ToString() +
                            " pOverlapped:" + ((int)nativeOverlapped).ToString());

            //
            // complete the IO and invoke the user's callback
            //
            if (errorCode != 0)
            {
                //
                // The Async IO completed with a failure.
                // here we need to call WSAGetOverlappedResult() just so WSAGetLastError() will return the correct error.
                //
                bool success =
                    UnsafeNclNativeMethods.OSSOCK.WSAGetOverlappedResult(
                        ((Socket)asyncResult.AsyncObject).Handle,
                        (IntPtr)nativeOverlapped,
                        out numBytes,
                        false,
                        IntPtr.Zero);

                GlobalLog.Assert(!success, "OverlappedAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::CompletionPortCallback() success: errorCode:" + errorCode + " numBytes:" + numBytes, "");

                errorCode = UnsafeNclNativeMethods.OSSOCK.WSAGetLastError();

                GlobalLog.Assert(errorCode != 0, "OverlappedAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::CompletionPortCallback() errorCode is 0 numBytes:" + numBytes, "");
            }

            //
            // this will release the unmanaged pin handles and unmanaged overlapped ptr
            //
            asyncResult.ReleaseUnmanagedStructures();
            asyncResult.ErrorCode = (int)errorCode;
            asyncResult.InvokeCallback(false, (int)numBytes);
        }
        //
        // The overlapped function called (either by the thread pool or the socket)
        // when IO completes. (only called on Win9x)
        //
        internal void OverlappedCallback(object stateObject, bool Signaled)
        {
            OverlappedAsyncResult asyncResult = (OverlappedAsyncResult)stateObject;

            GlobalLog.Assert(!asyncResult.IsCompleted, "OverlappedAsyncResult#" + ValidationHelper.HashString(asyncResult) + "::OverlappedCallback() asyncResult.IsCompleted", "");
            //
            // the IO completed asynchronously, see if there was a failure the Internal
            // field in the Overlapped structure will be non zero. to optimize the non
            // error case, we look at it without calling WSAGetOverlappedResult().
            //
            uint errorCode = (uint)Marshal.ReadInt32(IntPtrHelper.Add(asyncResult.m_UnmanagedBlob, Win32.OverlappedInternalOffset));
            uint numBytes  = errorCode != 0 ? unchecked ((uint)-1) : (uint)Marshal.ReadInt32(IntPtrHelper.Add(asyncResult.m_UnmanagedBlob, Win32.OverlappedInternalHighOffset));

            //
            // this will release the unmanaged pin handles and unmanaged overlapped ptr
            //
            asyncResult.ReleaseUnmanagedStructures();
            asyncResult.ErrorCode = (int)errorCode;
            asyncResult.InvokeCallback(false, (int)numBytes);
        }