Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK committed Feb 24, 2025
1 parent 427a5bd commit 81ad06f
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/Grpc.Net.Client/Balancer/Internal/ConnectionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ internal sealed class ConnectionManager : IDisposable, IChannelControlHelper
private static readonly ChannelIdProvider _channelIdProvider = new ChannelIdProvider();

private readonly object _lock;
private readonly object _subChannelStateChangedLock;
internal readonly Resolver _resolver;
private readonly ISubchannelTransportFactory _subchannelTransportFactory;
private readonly List<Subchannel> _subchannels;
Expand All @@ -57,6 +58,7 @@ internal ConnectionManager(
LoadBalancerFactory[] loadBalancerFactories)
{
_lock = new object();
_subChannelStateChangedLock = new object();
_nextPickerTcs = new TaskCompletionSource<SubchannelPicker>(TaskCreationOptions.RunContinuationsAsynchronously);
_resolverStartedTcs = new TaskCompletionSource<object?>(TaskCreationOptions.RunContinuationsAsynchronously);
_channelId = _channelIdProvider.GetNextChannelId();
Expand Down Expand Up @@ -204,7 +206,13 @@ internal void OnSubchannelStateChange(Subchannel subchannel, ConnectivityState s
}
}

subchannel.RaiseStateChanged(state, status);
// Lock to avoid parallel state change events.
// This is here so consumers of the state changed API don't need to worry about synchronization.
// Use a new lock to avoid deadlocks. See https://github.com/grpc/grpc-dotnet/issues/2589.
lock (_subChannelStateChangedLock)
{
subchannel.RaiseStateChanged(state, status);
}
}

public async Task ConnectAsync(bool waitForReady, CancellationToken cancellationToken)
Expand Down

0 comments on commit 81ad06f

Please sign in to comment.