private PooledStream Get(object owningObject, int result, ref bool continueLoop, ref WaitHandle[] waitHandles) { PooledStream fromPool = null; int num2 = result; switch (num2) { case 1: { int num = Interlocked.Decrement(ref this.m_WaitCount); continueLoop = false; Exception resError = this.m_ResError; if (num == 0) { this.CancelErrorCallback(); } throw resError; } case 2: try { continueLoop = true; fromPool = this.UserCreateRequest(); if (fromPool != null) { fromPool.PostPop(owningObject); Interlocked.Decrement(ref this.m_WaitCount); continueLoop = false; return(fromPool); } if (((this.Count >= this.MaxPoolSize) && (this.MaxPoolSize != 0)) && !this.ReclaimEmancipatedObjects()) { waitHandles = new WaitHandle[] { this.m_WaitHandles[0], this.m_WaitHandles[1] }; } return(fromPool); } finally { this.CreationMutex.ReleaseMutex(); } break; default: if (num2 == 0x102) { Interlocked.Decrement(ref this.m_WaitCount); continueLoop = false; throw new WebException(NetRes.GetWebStatusString("net_timeout", WebExceptionStatus.ConnectFailure), WebExceptionStatus.Timeout); } break; } Interlocked.Decrement(ref this.m_WaitCount); fromPool = this.GetFromPool(owningObject); continueLoop = false; return(fromPool); }
private PooledStream GetFromPool(object owningObject) { PooledStream stream = null; stream = (PooledStream)this.m_StackNew.Pop(); if (stream == null) { stream = (PooledStream)this.m_StackOld.Pop(); } if (stream != null) { stream.PostPop(owningObject); } return(stream); }
/// <summary> /// <para>Retrieves a pooled stream from the pool proper /// this work by first attemting to find something in the pool on the New stack /// and then trying the Old stack if something is not there availble </para> /// </summary> private PooledStream GetFromPool(object owningObject) { PooledStream res = null; GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool"); res = (PooledStream)m_StackNew.Pop(); if (null == res) { res = (PooledStream)m_StackOld.Pop(); } // Shouldn't be null, we could assert here. GlobalLog.Assert(res != null, "GetFromPool called with nothing in the pool!"); if (null != res) { res.PostPop(owningObject); GlobalLog.Print("GetFromGeneralPool pooledStream#" + ValidationHelper.HashString(res)); } GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool", ValidationHelper.HashString(res)); return(res); }
/// <summary> /// <para>Retrieves a pooled stream from the pool proper /// this work by first attemting to find something in the pool on the New stack /// and then trying the Old stack if something is not there availble </para> /// </summary> private PooledStream GetFromPool(object owningObject) { PooledStream res = null; GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool"); res = (PooledStream)m_StackNew.Pop(); if (null == res) { res = (PooledStream)m_StackOld.Pop(); } // The semaphore guaranteed that a connection was available so if res is // null it means that this contract has been violated somewhere GlobalLog.Assert(res != null, "GetFromPool called with nothing in the pool!"); if (null != res) { res.PostPop(owningObject); GlobalLog.Print("GetFromGeneralPool pooledStream#" + ValidationHelper.HashString(res)); } GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetFromPool", ValidationHelper.HashString(res)); return(res); }
/// <summary> /// <para>Retrieves the pooled stream out of the pool, does this by using the result /// of a WaitAny as input, and then based on whether it has a mutex, event, semaphore, /// or timeout decides what action to take</para> /// </summary> private PooledStream Get(object owningObject, int result, ref bool continueLoop, ref WaitHandle [] waitHandles) { PooledStream pooledStream = null; GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::Get", result.ToString()); // From the WaitAny docs: "If more than one object became signaled during // the call, this is the array index of the signaled object with the // smallest index value of all the signaled objects." This is important // so that the free object signal will be returned before a creation // signal. switch (result) { case WaitTimeout: Interlocked.Decrement(ref m_WaitCount); continueLoop = false; GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::Get", "throw Timeout WebException"); throw new WebException(NetRes.GetWebStatusString("net_timeout", WebExceptionStatus.ConnectFailure), WebExceptionStatus.Timeout); case ErrorHandleIndex: // Throw the error that PoolCreateRequest stashed. int newWaitCount = Interlocked.Decrement(ref m_WaitCount); continueLoop = false; Exception exceptionToThrow = m_ResError; if (newWaitCount == 0) { CancelErrorCallback(); } throw exceptionToThrow; case CreationHandleIndex: try { continueLoop = true; pooledStream = UserCreateRequest(); if (null != pooledStream) { pooledStream.PostPop(owningObject); Interlocked.Decrement(ref m_WaitCount); continueLoop = false; } else { // If we were not able to create an object, check to see if // we reached MaxPoolSize. If so, we will no longer wait on // the CreationHandle, but instead wait for a free object or // the timeout. // BUG - if we receive the CreationHandle midway into the wait // period and re-wait, we will be waiting on the full period if (Count >= MaxPoolSize && 0 != MaxPoolSize) { if (!ReclaimEmancipatedObjects()) { // modify handle array not to wait on creation mutex anymore waitHandles = new WaitHandle[2]; waitHandles[0] = m_WaitHandles[0]; waitHandles[1] = m_WaitHandles[1]; } } } } finally { CreationMutex.ReleaseMutex(); } break; default: // // guaranteed available inventory // Interlocked.Decrement(ref m_WaitCount); pooledStream = GetFromPool(owningObject); continueLoop = false; break; } GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::Get", ValidationHelper.HashString(pooledStream)); return(pooledStream); }