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