Skip to content

Commit

Permalink
Merge pull request #47 from aspriddell/reduce-locking
Browse files Browse the repository at this point in the history
Lock outside of a try-catch block
  • Loading branch information
aspriddell authored Dec 8, 2020
2 parents 95742e4 + 66fde6d commit ea334da
Showing 1 changed file with 13 additions and 21 deletions.
34 changes: 13 additions & 21 deletions DragonFruit.Common.Data/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,10 @@ public string Authorization

#region Clients, Hashes and Locks

private bool _clientAdjustmentInProgress;
private int _clientAdjustmentSignal;
private string _lastHandlerHash = string.Empty;
private string _lastHash = string.Empty;

private readonly object _clientAdjustmentLock = new object();
private long _currentRequests;

private HttpMessageHandler _handler;
Expand All @@ -129,34 +128,26 @@ public string Authorization
/// </summary>
protected HttpClient GetClient()
{
// if we're waiting, then don't cause a crash from the monitor below or from getting the wrong client - just wait.
while (_clientAdjustmentInProgress)
{
Thread.Sleep(AdjustmentTimeout / 2);
}

//if there's no edits return the current client (perform the check once instead of a potential twice)
// if there's no edits return the current client (perform the check once instead of a potential twice)
var changeHeaders = Headers.ChangesAvailable;

if (_lastHash == ClientHash && !changeHeaders)
{
return Client;
}

try
// if we're waiting, then don't cause a crash from the monitor below or from getting the wrong client - just wait.
while (Interlocked.CompareExchange(ref _clientAdjustmentSignal, 1, 0) == 1)
{
_clientAdjustmentInProgress = true;

//lock for modification
if (!Monitor.TryEnter(_clientAdjustmentLock, AdjustmentTimeout))
{
throw new TimeoutException($"The {nameof(ApiClient)} is being overloaded with reconstruction requests. Consider creating a separate {nameof(ApiClient)} and delegating clients to specific types of requests");
}
Timeout();
}

//wait for all ongoing requests to end
try
{
// wait for all ongoing requests to end
while (_currentRequests > 0)
{
Thread.Sleep(AdjustmentTimeout / 2);
Timeout();
}

var handlerHash = Handler.ItemHashCode();
Expand Down Expand Up @@ -189,8 +180,7 @@ protected HttpClient GetClient()
}
finally
{
_clientAdjustmentInProgress = false;
Monitor.Exit(_clientAdjustmentLock);
Interlocked.Decrement(ref _clientAdjustmentSignal);
}
}

Expand Down Expand Up @@ -375,5 +365,7 @@ protected virtual void ValidateRequest(ApiRequest request)
}
}
}

private void Timeout() => Thread.Sleep(AdjustmentTimeout / 2);
}
}

0 comments on commit ea334da

Please sign in to comment.