Skip to content

Commit

Permalink
Fix gRPC client retry deadlock (#2209)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored Jul 26, 2023
1 parent 2fc5ba6 commit 946610f
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/Grpc.Net.Client/Internal/Retry/HedgingCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,10 @@ private async Task HedgingDelayAsync(TimeSpan hedgingDelay)

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

lock (Lock)
{
base.Dispose(disposing);

CleanUpUnsynchronized();
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/Grpc.Net.Client/Internal/Retry/RetryCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,23 @@ private static bool IsSuccessfulStreamingCall(Status responseStatus, GrpcCall<TR

protected override void OnCommitCall(IGrpcCall<TRequest, TResponse> call)
{
Debug.Assert(Monitor.IsEntered(Lock));

_activeCall = null;
}

protected override void Dispose(bool disposing)
{
base.Dispose(disposing);

// Don't dispose the active call inside the retry lock.
// Canceling the call could cause callbacks to run on other threads that want to aquire this lock, causing an app deadlock.
GrpcCall<TRequest, TResponse>? activeCall = null;
lock (Lock)
{
base.Dispose(disposing);

_activeCall?.Dispose();
activeCall = _activeCall;
}
activeCall?.Dispose();
}

protected override void StartCore(Action<GrpcCall<TRequest, TResponse>> startCallFunc)
Expand Down

0 comments on commit 946610f

Please sign in to comment.