Exemplo n.º 1
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);
        }
Exemplo n.º 4
0
        private SocketError DoBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            GlobalLog.Print("Socket#" + Logging.HashString(this) + "::BeginReceive() size:" + size.ToString());

#if DEBUG
            IntPtr lastHandle = _handle.DangerousGetHandle();
#endif
            // Guarantee to call CheckAsyncCallOverlappedResult if we call SetUnamangedStructures with a cache in order to
            // avoid a Socket leak in case of error.
            SocketError errorCode = SocketError.SocketError;
            try
            {
                errorCode = SocketPal.ReceiveAsync(_handle, buffer, offset, size, socketFlags, asyncResult);

                GlobalLog.Print("Socket#" + Logging.HashString(this) + "::BeginReceive() Interop.Winsock.WSARecv returns:" + errorCode.ToString() + " returning AsyncResult:" + Logging.HashString(asyncResult));
            }
            finally
            {
                errorCode = asyncResult.CheckAsyncCallOverlappedResult(errorCode);
            }

            // Throw an appropriate SocketException if the native call fails synchronously.
            if (errorCode != SocketError.Success)
            {
                GlobalLog.Assert(errorCode != SocketError.Success, "Socket#{0}::DoBeginReceive()|GetLastWin32Error() returned zero.", Logging.HashString(this));

                // Update the internal state of this socket according to the error before throwing.
                UpdateStatusAfterSocketError(errorCode);
                if (s_loggingEnabled)
                {
                    Logging.Exception(Logging.Sockets, this, "BeginReceive", new SocketException((int)errorCode));
                }
                asyncResult.InvokeCallback(new SocketException((int)errorCode));
            }
#if DEBUG
            else
            {
                _lastReceiveHandle = lastHandle;
                _lastReceiveThread = Environment.CurrentManagedThreadId;
                _lastReceiveTick = Environment.TickCount;
            }
#endif

            return errorCode;
        }
Exemplo n.º 5
0
        private SocketError DoBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginReceive() size:" + size.ToString());

#if DEBUG
            IntPtr lastHandle = m_Handle.DangerousGetHandle();
#endif
            // Guarantee to call CheckAsyncCallOverlappedResult if we call SetUnamangedStructures with a cache in order to
            // avoid a Socket leak in case of error.
            SocketError errorCode = SocketError.SocketError;
            try
            {
                // Set up asyncResult for overlapped WSARecv.
                // This call will use completion ports on WinNT and Overlapped IO on Win9x.
                asyncResult.SetUnmanagedStructures(buffer, offset, size, null, false /* don't pin null RemoteEP*/, ref Caches.ReceiveOverlappedCache);

                // This can throw ObjectDisposedException.
                int bytesTransferred;
                errorCode = UnsafeNclNativeMethods.OSSOCK.WSARecv(
                    m_Handle,
                    ref asyncResult.m_SingleBuffer,
                    1,
                    out bytesTransferred,
                    ref socketFlags,
                    asyncResult.OverlappedHandle,
                    IntPtr.Zero);

                if (errorCode!=SocketError.Success) {
                    errorCode = (SocketError)Marshal.GetLastWin32Error();
                    GlobalLog.Assert(errorCode != SocketError.Success, "Socket#{0}::DoBeginReceive()|GetLastWin32Error() returned zero.", ValidationHelper.HashString(this));
                }
                GlobalLog.Print("Socket#" + ValidationHelper.HashString(this) + "::BeginReceive() UnsafeNclNativeMethods.OSSOCK.WSARecv returns:" + errorCode.ToString() + " bytesTransferred:" + bytesTransferred.ToString() + " returning AsyncResult:" + ValidationHelper.HashString(asyncResult));
            }
            finally
            {
                errorCode = asyncResult.CheckAsyncCallOverlappedResult(errorCode);
            }

            //
            // if the asynchronous native call fails synchronously
            // we'll throw a SocketException
            //
            if (errorCode != SocketError.Success)
            {
                //
                // update our internal state after this socket error and throw
                asyncResult.ExtractCache(ref Caches.ReceiveOverlappedCache);
                UpdateStatusAfterSocketError(errorCode);
                if(s_LoggingEnabled)Logging.Exception(Logging.Sockets, this, "BeginReceive", new SocketException(errorCode));
                asyncResult.InvokeCallback(new SocketException(errorCode));
            }
#if DEBUG
            else
            {
                m_LastReceiveHandle = lastHandle;
                m_LastReceiveThread = Thread.CurrentThread.ManagedThreadId;
                m_LastReceiveTick = Environment.TickCount;
            }
#endif

            return errorCode;
        }
Exemplo n.º 6
0
 private SocketError DoBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
 {
     SocketError socketError = SocketError.SocketError;
       try
       {
     asyncResult.SetUnmanagedStructures(buffer, offset, size, (SocketAddress) null, false, ref this.Caches.ReceiveOverlappedCache);
     int bytesTransferred;
     socketError = UnsafeNclNativeMethods.OSSOCK.WSARecv(this.m_Handle, ref asyncResult.m_SingleBuffer, 1, out bytesTransferred, out socketFlags, asyncResult.OverlappedHandle, IntPtr.Zero);
     if (socketError != SocketError.Success)
       socketError = (SocketError) Marshal.GetLastWin32Error();
       }
       finally
       {
     socketError = asyncResult.CheckAsyncCallOverlappedResult(socketError);
       }
       if (socketError != SocketError.Success)
       {
     asyncResult.ExtractCache(ref this.Caches.ReceiveOverlappedCache);
     this.UpdateStatusAfterSocketError(socketError);
     if (Socket.s_LoggingEnabled)
       Logging.Exception(Logging.Sockets, (object) this, "BeginReceive", (Exception) new SocketException(socketError));
     asyncResult.InvokeCallback((object) new SocketException(socketError));
       }
       return socketError;
 }
Exemplo n.º 7
0
        private SocketError DoBeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, OverlappedAsyncResult asyncResult)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"size:{size}");

#if DEBUG
            IntPtr lastHandle = _handle.DangerousGetHandle();
#endif
            // Guarantee to call CheckAsyncCallOverlappedResult if we call SetUnamangedStructures with a cache in order to
            // avoid a Socket leak in case of error.
            SocketError errorCode = SocketError.SocketError;
            try
            {
                errorCode = SocketPal.ReceiveAsync(_handle, buffer, offset, size, socketFlags, asyncResult);

                if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Interop.Winsock.WSARecv returns:{errorCode} returning AsyncResult:{asyncResult}");
            }
            finally
            {
                errorCode = asyncResult.CheckAsyncCallOverlappedResult(errorCode);
            }

            // Throw an appropriate SocketException if the native call fails synchronously.
            if (errorCode != SocketError.Success)
            {
                // TODO: https://github.com/dotnet/corefx/issues/5426
                // NetEventSource.Fail(this, "GetLastWin32Error() returned zero.");

                // Update the internal state of this socket according to the error before throwing.
                UpdateStatusAfterSocketError(errorCode);
                var socketException = new SocketException((int)errorCode);
                if (NetEventSource.IsEnabled) NetEventSource.Error(this, socketException);
                asyncResult.InvokeCallback(new SocketException((int)errorCode));
            }
#if DEBUG
            else
            {
                _lastReceiveHandle = lastHandle;
                _lastReceiveThread = Environment.CurrentManagedThreadId;
                _lastReceiveTick = Environment.TickCount;
            }
#endif

            return errorCode;
        }