internal PooledStream GetConnection(object owningObject, GeneralAsyncDelegate asyncCallback, int creationTimeout) { int num; PooledStream pooledStream = null; bool continueLoop = true; bool flag2 = asyncCallback != null; if (this.m_State != State.Running) { throw new InternalException(); } Interlocked.Increment(ref this.m_WaitCount); WaitHandle[] waitHandles = this.m_WaitHandles; if (!flag2) { while ((pooledStream == null) && continueLoop) { num = WaitHandle.WaitAny(waitHandles, creationTimeout, false); pooledStream = this.Get(owningObject, num, ref continueLoop, ref waitHandles); } } else { num = WaitHandle.WaitAny(waitHandles, 0, false); if (num != 0x102) { pooledStream = this.Get(owningObject, num, ref continueLoop, ref waitHandles); } if (pooledStream == null) { AsyncConnectionPoolRequest asyncRequest = new AsyncConnectionPoolRequest(this, owningObject, asyncCallback, creationTimeout); this.QueueRequest(asyncRequest); } } if (pooledStream != null) { if (!pooledStream.IsInitalizing) { asyncCallback = null; } try { if (!pooledStream.Activate(owningObject, asyncCallback)) { pooledStream = null; } return(pooledStream); } catch { this.PutConnection(pooledStream, owningObject, creationTimeout, false); throw; } } if (!flag2) { throw new InternalException(); } return(pooledStream); }
/// <summary> /// <para>Queues a AsyncConnectionPoolRequest to our queue of requests needing /// a pooled stream. If an AsyncThread is not created, we create one, /// and let it process the queued items</para> /// </summary> private void QueueRequest(AsyncConnectionPoolRequest asyncRequest) { lock (m_QueuedRequests) { m_QueuedRequests.Enqueue(asyncRequest); if (m_AsyncThread == null) { m_AsyncThread = new Thread(new ThreadStart(AsyncThread)); m_AsyncThread.IsBackground = true; m_AsyncThread.Start(); } } }
/// <summary> /// <para>Processes async queued requests that are blocked on needing a free pooled stream /// works as follows: /// 1. while there are blocked requests, take one out of the queue /// 2. Wait for a free connection, when one becomes avail, then notify the request that its there /// 3. repeat 1 until there are no more queued requests /// 4. if there are no more requests waiting to for a free stream, then close down this thread ///</para> /// </summary> private void AsyncThread() { do { while (m_QueuedRequests.Count > 0) { bool continueLoop = true; AsyncConnectionPoolRequest asyncState = null; lock (m_QueuedRequests) { asyncState = (AsyncConnectionPoolRequest)m_QueuedRequests.Dequeue(); } WaitHandle [] localWaitHandles = m_WaitHandles; PooledStream PooledStream = null; try { while ((PooledStream == null) && continueLoop) { int result = WaitHandle.WaitAny(localWaitHandles, asyncState.CreationTimeout, false); PooledStream = Get(asyncState.OwningObject, result, ref continueLoop, ref localWaitHandles); } PooledStream.Activate(asyncState.OwningObject, asyncState.AsyncCallback); } catch (Exception e) { if (PooledStream != null) { PooledStream.Close(); PutConnection(PooledStream, asyncState.OwningObject, asyncState.CreationTimeout); } asyncState.AsyncCallback(asyncState.OwningObject, e); } catch { if (PooledStream != null) { PooledStream.Close(); PutConnection(PooledStream, asyncState.OwningObject, asyncState.CreationTimeout); } asyncState.AsyncCallback(asyncState.OwningObject, new Exception(SR.GetString(SR.net_nonClsCompliantException))); } } Thread.Sleep(500); lock (m_QueuedRequests) { if (m_QueuedRequests.Count == 0) { m_AsyncThread = null; break; } } } while (true); }
private void AsyncThread() { Label_00B1: while (this.m_QueuedRequests.Count > 0) { bool continueLoop = true; AsyncConnectionPoolRequest request = null; lock (this.m_QueuedRequests) { request = (AsyncConnectionPoolRequest)this.m_QueuedRequests.Dequeue(); } WaitHandle[] waitHandles = this.m_WaitHandles; PooledStream pooledStream = null; try { while ((pooledStream == null) && continueLoop) { int result = WaitHandle.WaitAny(waitHandles, request.CreationTimeout, false); pooledStream = this.Get(request.OwningObject, result, ref continueLoop, ref waitHandles); } pooledStream.Activate(request.OwningObject, request.AsyncCallback); continue; } catch (Exception exception) { if (pooledStream != null) { this.PutConnection(pooledStream, request.OwningObject, request.CreationTimeout, false); } request.AsyncCallback(request.OwningObject, exception); continue; } } Thread.Sleep(500); lock (this.m_QueuedRequests) { if (this.m_QueuedRequests.Count == 0) { this.m_AsyncThread = null; } else { goto Label_00B1; } } }
/// <devdoc> /// <para>Attempts to create a PooledStream, by trying to get a pooled Connection, /// or by creating its own new one</para> /// </devdoc> internal PooledStream GetConnection(object owningObject, GeneralAsyncDelegate asyncCallback, int creationTimeout) { int result; PooledStream stream = null; bool continueLoop = true; bool async = (asyncCallback != null) ? true : false; GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetConnection"); if(m_State != State.Running) { throw new InternalException(); } Interlocked.Increment(ref m_WaitCount); WaitHandle[] localWaitHandles = m_WaitHandles; if (async) { result = WaitHandle.WaitAny(localWaitHandles, 0, false); if (result != WaitTimeout) { stream = Get(owningObject, result, ref continueLoop, ref localWaitHandles); } if (stream == null) { GlobalLog.Print("GetConnection:"+ValidationHelper.HashString(this)+" going async"); AsyncConnectionPoolRequest asyncState = new AsyncConnectionPoolRequest(this, owningObject, asyncCallback, creationTimeout); QueueRequest(asyncState); } } else { // loop while we don't have an error/timeout and we haven't gotten a stream yet while ((stream == null) && continueLoop) { result = WaitHandle.WaitAny(localWaitHandles, creationTimeout, false); stream = Get(owningObject, result, ref continueLoop, ref localWaitHandles); } } if (null != stream) { // if there is already a stream, then we're not going async if (!stream.IsInitalizing) { asyncCallback = null; } try{ // If activate returns false, it is going to finish asynchronously // and therefore the stream will be returned in a callback and // we should not return it here (return null) if (stream.Activate(owningObject, asyncCallback) == false) stream = null; } catch{ stream.Close(); PutConnection(stream,owningObject,creationTimeout); throw; } } else if (!async) { throw new InternalException(); } GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetConnection", ValidationHelper.HashString(stream)); return(stream); }
/// <summary> /// <para>Queues a AsyncConnectionPoolRequest to our queue of requests needing /// a pooled stream. If an AsyncThread is not created, we create one, /// and let it process the queued items</para> /// </summary> private void QueueRequest(AsyncConnectionPoolRequest asyncRequest) { lock(m_QueuedRequests) { m_QueuedRequests.Enqueue(asyncRequest); if (m_AsyncThread == null) { m_AsyncThread = new Thread(new ThreadStart(AsyncThread)); m_AsyncThread.IsBackground = true; m_AsyncThread.Start(); } } }
/// <devdoc> /// <para>Attempts to create a PooledStream, by trying to get a pooled Connection, /// or by creating its own new one</para> /// </devdoc> internal PooledStream GetConnection(object owningObject, GeneralAsyncDelegate asyncCallback, int creationTimeout) { int result; PooledStream stream = null; bool continueLoop = true; bool async = (asyncCallback != null) ? true : false; GlobalLog.Enter("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetConnection"); if (m_State != State.Running) { throw new InternalException(); } Interlocked.Increment(ref m_WaitCount); WaitHandle[] localWaitHandles = m_WaitHandles; if (async) { result = WaitHandle.WaitAny(localWaitHandles, 0, false); if (result != WaitTimeout) { stream = Get(owningObject, result, ref continueLoop, ref localWaitHandles); } if (stream == null) { GlobalLog.Print("GetConnection:" + ValidationHelper.HashString(this) + " going async"); AsyncConnectionPoolRequest asyncState = new AsyncConnectionPoolRequest(this, owningObject, asyncCallback, creationTimeout); QueueRequest(asyncState); } } else { // loop while we don't have an error/timeout and we haven't gotten a stream yet while ((stream == null) && continueLoop) { result = WaitHandle.WaitAny(localWaitHandles, creationTimeout, false); stream = Get(owningObject, result, ref continueLoop, ref localWaitHandles); } } if (null != stream) { // if there is already a stream, then we're not going async if (!stream.IsInitalizing) { asyncCallback = null; } try{ // If activate returns false, it is going to finish asynchronously // and therefore the stream will be returned in a callback and // we should not return it here (return null) if (stream.Activate(owningObject, asyncCallback) == false) { stream = null; } } catch { stream.Close(); PutConnection(stream, owningObject, creationTimeout); throw; } } else if (!async) { throw new InternalException(); } GlobalLog.Leave("ConnectionPool#" + ValidationHelper.HashString(this) + "::GetConnection", ValidationHelper.HashString(stream)); return(stream); }
internal PooledStream GetConnection(object owningObject, GeneralAsyncDelegate asyncCallback, int creationTimeout) { int num; PooledStream pooledStream = null; bool continueLoop = true; bool flag2 = asyncCallback != null; if (this.m_State != State.Running) { throw new InternalException(); } Interlocked.Increment(ref this.m_WaitCount); WaitHandle[] waitHandles = this.m_WaitHandles; if (!flag2) { while ((pooledStream == null) && continueLoop) { num = WaitHandle.WaitAny(waitHandles, creationTimeout, false); pooledStream = this.Get(owningObject, num, ref continueLoop, ref waitHandles); } } else { num = WaitHandle.WaitAny(waitHandles, 0, false); if (num != 0x102) { pooledStream = this.Get(owningObject, num, ref continueLoop, ref waitHandles); } if (pooledStream == null) { AsyncConnectionPoolRequest asyncRequest = new AsyncConnectionPoolRequest(this, owningObject, asyncCallback, creationTimeout); this.QueueRequest(asyncRequest); } } if (pooledStream != null) { if (!pooledStream.IsInitalizing) { asyncCallback = null; } try { if (!pooledStream.Activate(owningObject, asyncCallback)) { pooledStream = null; } return pooledStream; } catch { this.PutConnection(pooledStream, owningObject, creationTimeout, false); throw; } } if (!flag2) { throw new InternalException(); } return pooledStream; }