// // 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); }
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; }
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; }
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; }
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; }