private void PoolCreateRequest(object state) { // called by pooler to ensure pool requests are currently being satisfied - // creation mutex has not been obtained if (State.Running == _state) { // in case WaitForPendingOpen ever failed with no subsequent OpenAsync calls, // start it back up again if (!_pendingOpens.IsEmpty && _pendingOpensWaiting == 0) { Thread waitOpenThread = new Thread(WaitForPendingOpen); waitOpenThread.IsBackground = true; waitOpenThread.Start(); } // Before creating any new objects, reclaim any released objects that were // not closed. ReclaimEmancipatedObjects(); if (!ErrorOccurred) { if (NeedToReplenish) { // Check to see if pool was created using integrated security and if so, make // sure the identity of current user matches that of user that created pool. // If it doesn't match, do not create any objects on the ThreadPool thread, // since either Open will fail or we will open a object for this pool that does // not belong in this pool. The side effect of this is that if using integrated // security min pool size cannot be guaranteed. if (UsingIntegrateSecurity && !_identity.Equals(DbConnectionPoolIdentity.GetCurrent())) { return; } int waitResult = BOGUS_HANDLE; try { try { } finally { waitResult = WaitHandle.WaitAny(_waitHandles.GetHandles(withCreate: true), CreationTimeout); } if (CREATION_HANDLE == waitResult) { DbConnectionInternal newObj; // Check ErrorOccurred again after obtaining mutex if (!ErrorOccurred) { while (NeedToReplenish) { // Don't specify any user options because there is no outer connection associated with the new connection newObj = CreateObject(owningObject: null, userOptions: null, oldConnection: null); // We do not need to check error flag here, since we know if // CreateObject returned null, we are in error case. if (null != newObj) { PutNewObject(newObj); } else { break; } } } } else if (WaitHandle.WaitTimeout == waitResult) { // do not wait forever and potential block this worker thread // instead wait for a period of time and just requeue to try again QueuePoolCreateRequest(); } } finally { if (CREATION_HANDLE == waitResult) { // reuse waitResult and ignore its value _waitHandles.CreationSemaphore.Release(1); } } } } } }