mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-31 03:51:29 +02:00
[client] fix WaitStreamConnected stale-channel race
The StreamConnected check and the wait-channel creation took the mutex separately, so notifyStreamConnected could set the status and close/clear connectedCh in between: the waiter then created a fresh channel nobody would ever close and blocked forever. Also, the status read was unlocked while notify wrote it under the mutex (a data race). Do the check and the channel fetch in one locked section; drop the now-unused getStreamStatusChan helper. Pre-existing bug, not introduced by this branch.
This commit is contained in:
@@ -213,15 +213,6 @@ func (c *GrpcClient) notifyStreamConnected() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *GrpcClient) getStreamStatusChan() <-chan struct{} {
|
||||
c.mux.Lock()
|
||||
defer c.mux.Unlock()
|
||||
if c.connectedCh == nil {
|
||||
c.connectedCh = make(chan struct{})
|
||||
}
|
||||
return c.connectedCh
|
||||
}
|
||||
|
||||
func (c *GrpcClient) connect(ctx context.Context, key string) (proto.SignalExchange_ConnectStreamClient, error) {
|
||||
c.stream = nil
|
||||
|
||||
@@ -283,12 +274,21 @@ func (c *GrpcClient) IsHealthy() bool {
|
||||
|
||||
// WaitStreamConnected waits until the client is connected to the Signal stream
|
||||
func (c *GrpcClient) WaitStreamConnected(ctx context.Context) {
|
||||
|
||||
// Check the status and obtain the wait channel atomically: otherwise
|
||||
// notifyStreamConnected could flip the status and close/clear the channel
|
||||
// between the check and the channel creation, leaving us waiting forever on
|
||||
// a stale channel.
|
||||
c.mux.Lock()
|
||||
if c.status == StreamConnected {
|
||||
c.mux.Unlock()
|
||||
return
|
||||
}
|
||||
if c.connectedCh == nil {
|
||||
c.connectedCh = make(chan struct{})
|
||||
}
|
||||
ch := c.connectedCh
|
||||
c.mux.Unlock()
|
||||
|
||||
ch := c.getStreamStatusChan()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-c.ctx.Done():
|
||||
|
||||
Reference in New Issue
Block a user