Skip to content

Commit aabb906

Browse files
Cleanup semaphore holder
1 parent 36fefac commit aabb906

File tree

1 file changed

+32
-54
lines changed

1 file changed

+32
-54
lines changed

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/WaitHandleDbConnectionPool.cs

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)