internal OverlappedCache(System.Threading.Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback) { this.m_Overlapped = overlapped; this.m_PinnedObjects = pinnedObjectsArray; this.m_PinnedObjectsArray = pinnedObjectsArray; this.m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray)); }
// SetUnmanagedStructures // // This needs to be called for overlapped IO to function properly. // // Fills in overlapped Structures used in an async overlapped Winsock call. // These calls are outside the runtime and are unmanaged code, so we need // to prepare specific structures and ints that lie in unmanaged memory // since the overlapped calls may complete asynchronously. internal void SetUnmanagedStructures(object objectsToPin) { Socket s = (Socket)AsyncObject; // Bind the Win32 Socket Handle to the ThreadPool Debug.Assert(s != null, "m_CurrentSocket is null"); Debug.Assert(s.SafeHandle != null, "m_CurrentSocket.SafeHandle is null"); if (s.SafeHandle.IsInvalid) { throw new ObjectDisposedException(s.GetType().FullName); } ThreadPoolBoundHandle boundHandle = s.SafeHandle.GetOrAllocateThreadPoolBoundHandle(); unsafe { NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped(s_ioCallback, this, objectsToPin); _nativeOverlapped = new SafeNativeOverlapped(s.SafeHandle, overlapped); if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"{boundHandle}::AllocateNativeOverlapped. return={_nativeOverlapped}"); } } }
internal OverlappedCache(System.Threading.Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast) { this.m_Overlapped = overlapped; this.m_PinnedObjects = pinnedObjects; this.m_PinnedObjectsArray = alreadyTriedCast ? null : NclConstants.EmptyObjectArray; this.m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjects)); }
// SetUnmanagedStructures // // This needs to be called for overlapped IO to function properly. // // Fills in overlapped Structures used in an async overlapped Winsock call. // These calls are outside the runtime and are unmanaged code, so we need // to prepare specific structures and ints that lie in unmanaged memory // since the overlapped calls may complete asynchronously. internal void SetUnmanagedStructures(object objectsToPin) { Socket s = (Socket)AsyncObject; // Bind the Win32 Socket Handle to the ThreadPool Debug.Assert(s != null, "m_CurrentSocket is null"); Debug.Assert(s.SafeHandle != null, "m_CurrentSocket.SafeHandle is null"); if (s.SafeHandle.IsInvalid) { throw new ObjectDisposedException(s.GetType().FullName); } ThreadPoolBoundHandle boundHandle = s.SafeHandle.GetOrAllocateThreadPoolBoundHandle(); unsafe { NativeOverlapped *overlapped = boundHandle.AllocateNativeOverlapped(s_ioCallback, this, objectsToPin); _nativeOverlapped = new SafeNativeOverlapped(s.SafeHandle, overlapped); if (GlobalLog.IsEnabled) { GlobalLog.Print( "BaseOverlappedAsyncResult#" + LoggingHash.HashString(this) + "::boundHandle#" + LoggingHash.HashString(boundHandle) + "::AllocateNativeOverlapped. Return=" + _nativeOverlapped.DangerousGetHandle().ToString("x")); } } }
// Utility cleanup routine. Frees the overlapped structure. // This should be overridden to free pinned and unmanaged memory in the subclass. // It needs to also be invoked from the subclass. protected virtual void ForceReleaseUnmanagedStructures() { // Free the unmanaged memory if allocated. if (NetEventSource.IsEnabled) { NetEventSource.Enter(this); } _nativeOverlapped.Dispose(); _nativeOverlapped = null; GC.SuppressFinalize(this); }
internal OverlappedCache(Overlapped overlapped, object[] pinnedObjectsArray, IOCompletionCallback callback) { m_Overlapped = overlapped; m_PinnedObjects = pinnedObjectsArray; m_PinnedObjectsArray = pinnedObjectsArray; unsafe { m_NativeOverlapped = new SafeNativeOverlapped(overlapped.UnsafePack(callback, pinnedObjectsArray)); } }
// Utility cleanup routine. Frees the overlapped structure. // This should be overriden to free pinned and unmanaged memory in the subclass. // It needs to also be invoked from the subclass. protected virtual void ForceReleaseUnmanagedStructures() { // Free the unmanaged memory if allocated. GlobalLog.Print( "BaseOverlappedAsyncResult#" + Logging.HashString(this) + "::ForceReleaseUnmanagedStructures"); _nativeOverlapped.Dispose(); _nativeOverlapped = null; GC.SuppressFinalize(this); }
private void InternalFree() { this.m_Overlapped = null; this.m_PinnedObjects = null; if (this.m_NativeOverlapped != null) { if (!this.m_NativeOverlapped.IsInvalid) { this.m_NativeOverlapped.Dispose(); } this.m_NativeOverlapped = null; } }
private void InternalFree() { m_Overlapped = null; m_PinnedObjects = null; if (m_NativeOverlapped != null) { if (!m_NativeOverlapped.IsInvalid) { m_NativeOverlapped.Dispose(); } m_NativeOverlapped = null; } }
internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped) { EnsureDynamicWinsockMethods(); TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate <TransmitPacketsDelegate>(socketHandle); // UseDefaultWorkerThread = 0. return(transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, 0)); }
internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped, TransmitFileOptions flags) { EnsureDynamicWinsockMethods(); TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate <TransmitPacketsDelegate>(socketHandle); return(transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, flags)); }
// // This method is called after an asynchronous call is made for the user, // it checks and acts accordingly if the IO: // 1) completed synchronously. // 2) was pended. // 3) failed. // internal unsafe SocketError CheckAsyncCallOverlappedResult(SocketError errorCode) { #if DEBUG m_SavedErrorCode = errorCode; #endif // // Check if the Async IO call: // 1) was pended. // 2) completed synchronously. // 3) failed. // if (m_UseOverlappedIO) { // // we're using overlapped IO under Win9x (or NT with registry setting overriding // completion port usage) // switch (errorCode) { case 0: case SocketError.IOPending: // // the Async IO call was pended: // Queue our event to the thread pool. // GlobalLog.Assert(m_UnmanagedBlob != null, "BaseOverlappedAsyncResult#{0}::CheckAsyncCallOverlappedResult()|Unmanaged blob isn't allocated.", ValidationHelper.HashString(this)); ThreadPool.UnsafeRegisterWaitForSingleObject( m_OverlappedEvent, new WaitOrTimerCallback(OverlappedCallback), this, -1, true); // // we're done, completion will be asynchronous // in the callback. return // return(SocketError.Success); default: // // the Async IO call failed: // set the number of bytes transferred to -1 (error) // ErrorCode = (int)errorCode; Result = -1; ReleaseUnmanagedStructures(); break; } } else { #if DEBUG OverlappedCache cache = m_Cache; if (cache != null) { SafeNativeOverlapped nativeOverlappedPtr = cache.NativeOverlapped; if (nativeOverlappedPtr != null) { m_IntermediateNativeOverlapped = nativeOverlappedPtr; } } #endif // // We're using completion ports under WinNT. Release one reference on the structures for // the main thread. // ReleaseUnmanagedStructures(); switch (errorCode) { // // ignore cases in which a completion packet will be queued: // we'll deal with this IO in the callback // case 0: case SocketError.IOPending: // // ignore, do nothing // return(SocketError.Success); // // in the remaining cases a completion packet will NOT be queued: // we'll have to call the callback explicitly signaling an error // default: // // call the callback with error code // ErrorCode = (int)errorCode; Result = -1; // The AsyncResult must be cleared since the callback isn't going to be called. // Not doing so leads to a leak where the pinned cached OverlappedData continues to point to the async result object, // which points to the Socket (as well as user data) and to the OverlappedCache, preventing the OverlappedCache // finalizer from freeing the pinned OverlappedData. if (m_Cache != null) { // Could be null only if SetUnmanagedStructures weren't called. m_Cache.Overlapped.AsyncResult = null; } ReleaseUnmanagedStructures(); // Additional release for the completion that won't happen. break; } } return(errorCode); }
internal bool TransmitPackets(SafeCloseSocket socketHandle, IntPtr packetArray, int elementCount, int sendSize, SafeNativeOverlapped overlapped, TransmitFileOptions flags) { EnsureDynamicWinsockMethods(); TransmitPacketsDelegate transmitPackets = _dynamicWinsockMethods.GetDelegate<TransmitPacketsDelegate>(socketHandle); return transmitPackets(socketHandle, packetArray, elementCount, sendSize, overlapped, flags); }