public static SafeOverlappedFree Alloc(SafeCloseSocket socketHandle) { SafeOverlappedFree result = Alloc(); result._socketHandle = socketHandle; return(result); }
public static SafeOverlappedFree Alloc(SafeCloseSocket socketHandle) { SafeOverlappedFree free = Alloc(); free._socketHandle = socketHandle; return(free); }
public static SafeOverlappedFree Alloc() { SafeOverlappedFree result = UnsafeNclNativeMethods.SafeNetHandlesSafeOverlappedFree.LocalAlloc(LPTR, (UIntPtr)Win32.OverlappedSize); if (result.IsInvalid) { result.SetHandleAsInvalid(); throw new OutOfMemoryException(); } return(result); }
public static SafeOverlappedFree Alloc() { SafeOverlappedFree free = UnsafeNclNativeMethods.SafeNetHandlesSafeOverlappedFree.LocalAlloc(0x40, (UIntPtr)Win32.OverlappedSize); if (free.IsInvalid) { free.SetHandleAsInvalid(); throw new OutOfMemoryException(); } return(free); }
// 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. // ReleaseGCHandles(); GC.SuppressFinalize(this); if (m_UnmanagedBlob != null && !m_UnmanagedBlob.IsInvalid) { m_UnmanagedBlob.Close(true); m_UnmanagedBlob = null; } // This is interlocked because Cleanup() can be called simultaneously with ExtractCache(). OverlappedCache.InterlockedFree(ref m_Cache); if (m_OverlappedEvent != null) { m_OverlappedEvent.Close(); m_OverlappedEvent = null; } }
// // 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 can be Async // internal void SetUnmanagedStructures(object objectsToPin) { if (!m_DisableOverlapped) { // Casting to object[] is very expensive. Only do it once. object[] objectsToPinArray = null; bool triedCastingToArray = false; bool useCache = false; if (m_Cache != null) { if (objectsToPin == null && m_Cache.PinnedObjects == null) { useCache = true; } else if (m_Cache.PinnedObjects != null) { if (m_Cache.PinnedObjectsArray == null) { if (objectsToPin == m_Cache.PinnedObjects) { useCache = true; } } else if (objectsToPin != null) { triedCastingToArray = true; objectsToPinArray = objectsToPin as object[]; if (objectsToPinArray != null && objectsToPinArray.Length == 0) { objectsToPinArray = null; } if (objectsToPinArray != null && objectsToPinArray.Length == m_Cache.PinnedObjectsArray.Length) { useCache = true; for (int i = 0; i < objectsToPinArray.Length; i++) { if (objectsToPinArray[i] != m_Cache.PinnedObjectsArray[i]) { useCache = false; break; } } } } } } if (!useCache && m_Cache != null) { GlobalLog.Print("BaseOverlappedAsyncResult#" + ValidationHelper.HashString(this) + "::SetUnmanagedStructures() Cache miss - freeing cache."); m_Cache.Free(); m_Cache = null; } Socket s = (Socket) AsyncObject; if (m_UseOverlappedIO) { GlobalLog.Assert(m_UnmanagedBlob == null, "BaseOverlappedAsyncResult#{0}::SetUnmanagedStructures()|Unmanaged blob already allocated. (Called twice?)", ValidationHelper.HashString(this)); m_UnmanagedBlob = SafeOverlappedFree.Alloc(s.SafeHandle); PinUnmanagedObjects(objectsToPin); // // create the event handle // m_OverlappedEvent = new AutoResetEvent(false); // // fill in the overlapped structure with the event handle. // Marshal.WriteIntPtr( m_UnmanagedBlob.DangerousGetHandle(), Win32.OverlappedhEventOffset, m_OverlappedEvent.SafeWaitHandle.DangerousGetHandle() ); } else { // // Bind the Win32 Socket Handle to the ThreadPool // s.BindToCompletionPort(); if (m_Cache == null) { GlobalLog.Print("BaseOverlappedAsyncResult#" + ValidationHelper.HashString(this) + "::EnableCompletionPort() Creating new overlapped cache."); if (objectsToPinArray != null) { m_Cache = new OverlappedCache(new Overlapped(), objectsToPinArray, s_IOCallback); } else { m_Cache = new OverlappedCache(new Overlapped(), objectsToPin, s_IOCallback, triedCastingToArray); } } else { GlobalLog.Print("BaseOverlappedAsyncResult#" + ValidationHelper.HashString(this) + "::EnableCompletionPort() Using cached overlapped."); } m_Cache.Overlapped.AsyncResult = this; #if DEBUG unsafe { m_InitialNativeOverlapped = *((NativeOverlapped *) m_Cache.NativeOverlapped); } #endif GlobalLog.Print("BaseOverlappedAsyncResult#" + ValidationHelper.HashString(this) + "::EnableCompletionPort() overlapped:" + ValidationHelper.HashString(m_Cache.Overlapped) + " NativeOverlapped = " + m_Cache.NativeOverlapped.ToString("x")); } } }
internal void SetUnmanagedStructures(object objectsToPin) { if (!this.m_DisableOverlapped) { object[] pinnedObjectsArray = null; bool alreadyTriedCast = false; bool flag2 = false; if (this.m_Cache != null) { if ((objectsToPin == null) && (this.m_Cache.PinnedObjects == null)) { flag2 = true; } else if (this.m_Cache.PinnedObjects != null) { if (this.m_Cache.PinnedObjectsArray == null) { if (objectsToPin == this.m_Cache.PinnedObjects) { flag2 = true; } } else if (objectsToPin != null) { alreadyTriedCast = true; pinnedObjectsArray = objectsToPin as object[]; if ((pinnedObjectsArray != null) && (pinnedObjectsArray.Length == 0)) { pinnedObjectsArray = null; } if ((pinnedObjectsArray != null) && (pinnedObjectsArray.Length == this.m_Cache.PinnedObjectsArray.Length)) { flag2 = true; for (int i = 0; i < pinnedObjectsArray.Length; i++) { if (pinnedObjectsArray[i] != this.m_Cache.PinnedObjectsArray[i]) { flag2 = false; break; } } } } } } if (!flag2 && (this.m_Cache != null)) { this.m_Cache.Free(); this.m_Cache = null; } Socket asyncObject = (Socket) base.AsyncObject; if (this.m_UseOverlappedIO) { this.m_UnmanagedBlob = SafeOverlappedFree.Alloc(asyncObject.SafeHandle); this.PinUnmanagedObjects(objectsToPin); this.m_OverlappedEvent = new AutoResetEvent(false); Marshal.WriteIntPtr(this.m_UnmanagedBlob.DangerousGetHandle(), Win32.OverlappedhEventOffset, this.m_OverlappedEvent.SafeWaitHandle.DangerousGetHandle()); } else { asyncObject.BindToCompletionPort(); if (this.m_Cache == null) { if (pinnedObjectsArray != null) { this.m_Cache = new OverlappedCache(new Overlapped(), pinnedObjectsArray, s_IOCallback); } else { this.m_Cache = new OverlappedCache(new Overlapped(), objectsToPin, s_IOCallback, alreadyTriedCast); } } this.m_Cache.Overlapped.AsyncResult = this; } } }
protected virtual void ForceReleaseUnmanagedStructures() { this.ReleaseGCHandles(); GC.SuppressFinalize(this); if ((this.m_UnmanagedBlob != null) && !this.m_UnmanagedBlob.IsInvalid) { this.m_UnmanagedBlob.Close(true); this.m_UnmanagedBlob = null; } OverlappedCache.InterlockedFree(ref this.m_Cache); if (this.m_OverlappedEvent != null) { this.m_OverlappedEvent.Close(); this.m_OverlappedEvent = null; } }