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