@@ -40,6 +40,18 @@ final class GrpcXdsTransportFactory implements XdsTransportFactory {
4040 private final CallCredentials callCredentials ;
4141 // The map of xDS server info to its corresponding gRPC xDS transport.
4242 // This enables reusing and sharing the same underlying gRPC channel.
43+ //
44+ // NOTE: ConcurrentHashMap is used as a per-entry lock and all reads and writes must be a mutation
45+ // via the ConcurrentHashMap APIs to acquire the per-entry lock in order to ensure thread safety
46+ // for reference counting of each GrpcXdsTransport instance.
47+ //
48+ // WARNING: ServerInfo includes ChannelCredentials, which is compared by reference equality.
49+ // This means every BootstrapInfo would have non-equal copies of ServerInfo, even if they all
50+ // represent the same xDS server configuration. For gRPC name resolution with the `xds` and
51+ // `google-c2p` scheme, this transport sharing works as expected as it internally reuses a single
52+ // BootstrapInfo instance. Otherwise, new transports would be created for each ServerInfo despite
53+ // them possibly representing the same xDS server configuration and defeating the purpose of
54+ // transport sharing.
4355 private static final Map <Bootstrapper .ServerInfo , GrpcXdsTransport > xdsServerInfoToTransportMap =
4456 new ConcurrentHashMap <>();
4557
@@ -76,7 +88,7 @@ static class GrpcXdsTransport implements XdsTransport {
7688 private final ManagedChannel channel ;
7789 private final CallCredentials callCredentials ;
7890 private final Bootstrapper .ServerInfo serverInfo ;
79- // Must only be accessed within the provided atomic methods of ConcurrentHashMap .
91+ // Must only be accessed via the ConcurrentHashMap APIs which act as the locking methods .
8092 private int refCount = 0 ;
8193
8294 public GrpcXdsTransport (Bootstrapper .ServerInfo serverInfo ) {
0 commit comments