@@ -382,42 +382,6 @@ internal WaitHandle[] GetHandles(bool withCreate)
382382 return withCreate ? _handlesWithCreate : _handlesWithoutCreate ;
383383 }
384384 }
385-
386- /// <summary>
387- /// Helper class to obtain and release a semaphore.
388- /// </summary>
389- internal class SemaphoreHolder : IDisposable
390- {
391- private readonly Semaphore _semaphore ;
392-
393- /// <summary>
394- /// Whether the semaphore was successfully obtained within the timeout.
395- /// </summary>
396- internal bool Obtained { get ; private set ; }
397-
398- /// <summary>
399- /// Obtains the semaphore, waiting up to the specified timeout.
400- /// </summary>
401- /// <param name="semaphore"></param>
402- /// <param name="timeout"></param>
403- internal SemaphoreHolder ( Semaphore semaphore , int timeout )
404- {
405- _semaphore = semaphore ;
406- Obtained = _semaphore . WaitOne ( timeout ) ;
407- }
408-
409- /// <summary>
410- /// Releases the semaphore if it was successfully obtained.
411- /// </summary>
412- public void Dispose ( )
413- {
414- if ( Obtained )
415- {
416- _semaphore . Release ( 1 ) ;
417- }
418- }
419- }
420-
421385 private const int MAX_Q_SIZE = 0x00100000 ;
422386
423387 // The order of these is important; we want the WaitAny call to be signaled
@@ -1356,26 +1320,36 @@ private bool TryGetConnection(DbConnection owningObject, uint waitForMultipleObj
13561320
13571321 if ( onlyOneCheckConnection )
13581322 {
1359- using SemaphoreHolder semaphoreHolder = new ( _waitHandles . CreationSemaphore , unchecked ( ( int ) waitForMultipleObjectsTimeout ) ) ;
1360- if ( semaphoreHolder . Obtained )
1361- {
13621323#if NETFRAMEWORK
1363- RuntimeHelpers . PrepareConstrainedRegions ( ) ;
1324+ RuntimeHelpers . PrepareConstrainedRegions ( ) ;
13641325#endif
1365- SqlClientEventSource . Log . TryPoolerTraceEvent ( "<prov.DbConnectionPool.GetConnection|RES|CPOOL> {0}, Creating new connection." , Id ) ;
1366- obj = UserCreateRequest ( owningObject , userOptions ) ;
1326+ bool obtained = false ;
1327+ try
1328+ {
1329+ obtained = _waitHandles . CreationSemaphore . WaitOne ( unchecked ( ( int ) waitForMultipleObjectsTimeout ) ) ;
1330+ if ( obtained )
1331+ {
1332+ SqlClientEventSource . Log . TryPoolerTraceEvent ( "<prov.DbConnectionPool.GetConnection|RES|CPOOL> {0}, Creating new connection." , Id ) ;
1333+ obj = UserCreateRequest ( owningObject , userOptions ) ;
1334+ }
1335+ else
1336+ {
1337+ // Timeout waiting for creation semaphore - return null
1338+ SqlClientEventSource . Log . TryPoolerTraceEvent ( "<prov.DbConnectionPool.GetConnection|RES|CPOOL> {0}, Wait timed out." , Id ) ;
1339+ connection = null ;
1340+ return false ;
1341+ }
13671342 }
1368- else
1343+ finally
13691344 {
1370- // Timeout waiting for creation semaphore - return null
1371- SqlClientEventSource . Log . TryPoolerTraceEvent ( "<prov.DbConnectionPool.GetConnection|RES|CPOOL> {0}, Wait timed out." , Id ) ;
1372- connection = null ;
1373- return false ;
1345+ if ( obtained )
1346+ {
1347+ _waitHandles . CreationSemaphore . Release ( 1 ) ;
1348+ }
13741349 }
13751350 }
13761351 }
13771352 break ;
1378-
13791353 case WAIT_ABANDONED + SEMAPHORE_HANDLE :
13801354 SqlClientEventSource . Log . TryPoolerTraceEvent ( "<prov.DbConnectionPool.GetConnection|RES|CPOOL> {0}, Semaphore handle abandonded." , Id ) ;
13811355 Interlocked . Decrement ( ref _waitCount ) ;
@@ -1582,20 +1556,17 @@ private void PoolCreateRequest(object state)
15821556 {
15831557 return ;
15841558 }
1585-
15861559#if NETFRAMEWORK
15871560 RuntimeHelpers . PrepareConstrainedRegions ( ) ;
15881561#endif
1562+ bool obtained = false ;
15891563 try
15901564 {
15911565 // Obtain creation mutex so we're the only one creating objects
1592- using SemaphoreHolder semaphoreHolder = new ( _waitHandles . CreationSemaphore , CreationTimeout ) ;
1566+ obtained = _waitHandles . CreationSemaphore . WaitOne ( CreationTimeout ) ;
15931567
1594- if ( semaphoreHolder . Obtained )
1568+ if ( obtained )
15951569 {
1596- #if NETFRAMEWORK
1597- RuntimeHelpers . PrepareConstrainedRegions ( ) ;
1598- #endif
15991570 DbConnectionInternal newObj ;
16001571
16011572 // Check ErrorOccurred again after obtaining mutex
@@ -1648,6 +1619,13 @@ private void PoolCreateRequest(object state)
16481619 // thrown to the user the next time they request a connection.
16491620 SqlClientEventSource . Log . TryPoolerTraceEvent ( "<prov.DbConnectionPool.PoolCreateRequest|RES|CPOOL> {0}, PoolCreateRequest called CreateConnection which threw an exception: {1}" , Id , e ) ;
16501621 }
1622+ finally
1623+ {
1624+ if ( obtained )
1625+ {
1626+ _waitHandles . CreationSemaphore . Release ( 1 ) ;
1627+ }
1628+ }
16511629 }
16521630 }
16531631 }
0 commit comments