File tree Expand file tree Collapse file tree 2 files changed +15
-0
lines changed Expand file tree Collapse file tree 2 files changed +15
-0
lines changed Original file line number Diff line number Diff line change @@ -711,7 +711,12 @@ func (cc *ClientConn) switchBalancer(name string) {
711711 return
712712 }
713713 if cc .balancerWrapper != nil {
714+ // Don't hold cc.mu while closing the balancers. The balancers may call
715+ // methods that require cc.mu (e.g. cc.NewSubConn()). Holding the mutex
716+ // would cause a deadlock in that case.
717+ cc .mu .Unlock ()
714718 cc .balancerWrapper .close ()
719+ cc .mu .Lock ()
715720 }
716721
717722 builder := balancer .Get (name )
Original file line number Diff line number Diff line change @@ -39,6 +39,8 @@ type ccResolverWrapper struct {
3939 resolver resolver.Resolver
4040 done * grpcsync.Event
4141 curState resolver.State
42+
43+ incomingMu sync.Mutex // Synchronizes all the incoming calls.
4244}
4345
4446// newCCResolverWrapper uses the resolver.Builder to build a Resolver and
@@ -90,6 +92,8 @@ func (ccr *ccResolverWrapper) close() {
9092}
9193
9294func (ccr * ccResolverWrapper ) UpdateState (s resolver.State ) error {
95+ ccr .incomingMu .Lock ()
96+ defer ccr .incomingMu .Unlock ()
9397 if ccr .done .HasFired () {
9498 return nil
9599 }
@@ -105,6 +109,8 @@ func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
105109}
106110
107111func (ccr * ccResolverWrapper ) ReportError (err error ) {
112+ ccr .incomingMu .Lock ()
113+ defer ccr .incomingMu .Unlock ()
108114 if ccr .done .HasFired () {
109115 return
110116 }
@@ -114,6 +120,8 @@ func (ccr *ccResolverWrapper) ReportError(err error) {
114120
115121// NewAddress is called by the resolver implementation to send addresses to gRPC.
116122func (ccr * ccResolverWrapper ) NewAddress (addrs []resolver.Address ) {
123+ ccr .incomingMu .Lock ()
124+ defer ccr .incomingMu .Unlock ()
117125 if ccr .done .HasFired () {
118126 return
119127 }
@@ -128,6 +136,8 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
128136// NewServiceConfig is called by the resolver implementation to send service
129137// configs to gRPC.
130138func (ccr * ccResolverWrapper ) NewServiceConfig (sc string ) {
139+ ccr .incomingMu .Lock ()
140+ defer ccr .incomingMu .Unlock ()
131141 if ccr .done .HasFired () {
132142 return
133143 }
You can’t perform that action at this time.
0 commit comments