diff options
author | 2018-03-21 09:54:39 +0100 | |
---|---|---|
committer | 2018-03-21 09:54:39 +0100 | |
commit | 9b9807a48c2dcac806e7a8599bb28e0a605af495 (patch) | |
tree | 7ed9474c7f8095bcde7bfcee30b79c567ecca621 /src | |
parent | e5821cdad2a45072a0b023a8ea003cff4f03791f (diff) |
fix C# connectivity watcher shutdown race
Diffstat (limited to 'src')
-rw-r--r-- | src/csharp/Grpc.Core/Channel.cs | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index e7b30cd1e9..d4fcd1ad9c 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -160,8 +160,18 @@ namespace Grpc.Core var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; lock (myLock) { - // pass "tcs" as "state" for WatchConnectivityStateHandler. - handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, WatchConnectivityStateHandler, tcs); + if (handle.IsClosed) + { + // If channel has been already shutdown and handle was disposed, we would end up with + // an abandoned completion added to the completion registry. So we act as if the + // wait has timed out instead. + tcs.SetResult(false); + } + else + { + // pass "tcs" as "state" for WatchConnectivityStateHandler. + handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, WatchConnectivityStateHandler, tcs); + } } return tcs.Task; } |