Use Monitor.TryEnter/Exit in the Scan loop (#189)

- Avoids overlapping Scans
- Noops if dispose is being called at the same time
This commit is contained in:
David Fowler 2017-02-10 16:34:31 -08:00 committed by GitHub
parent 633c572a22
commit fc93c47789
1 changed files with 37 additions and 28 deletions

View File

@ -87,7 +87,16 @@ namespace Microsoft.AspNetCore.Sockets
private void Scan() private void Scan()
{ {
lock (_executionLock) // If we couldn't get the lock it means one of 2 things is true:
// - We're about to dispose so we don't care to run the scan callback anyways.
// - The previous Scan took long enough that the next scan tried to run in parallel
// In either case just do nothing and end the timer callback as soon as possible
if (!Monitor.TryEnter(_executionLock))
{
return;
}
try
{ {
if (_disposed) if (_disposed)
{ {
@ -97,8 +106,6 @@ namespace Microsoft.AspNetCore.Sockets
// Pause the timer while we're running // Pause the timer while we're running
_timer.Change(Timeout.Infinite, Timeout.Infinite); _timer.Change(Timeout.Infinite, Timeout.Infinite);
try
{
// Scan the registered connections looking for ones that have timed out // Scan the registered connections looking for ones that have timed out
foreach (var c in _connections) foreach (var c in _connections)
{ {
@ -130,7 +137,9 @@ namespace Microsoft.AspNetCore.Sockets
{ {
// Resume once we finished processing all connections // Resume once we finished processing all connections
_timer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)); _timer.Change(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
}
// Exit the lock now
Monitor.Exit(_executionLock);
} }
} }