server: Fix deadlock if StopBgp is called when conn queue is full #2771
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes a deadlock condition that can happen if StopBgp is called when the pending connection queue is full. During teardown, StopBgp calls a mgmtOp on the server goroutine which attempts to stop the goroutine accepting inbound connections, and waits for it to finish before continuing.
This connection goroutine can block if the connection queue is full, which is read by the same goroutine that processes all mgmtOps. This means that if the queue is full and the goroutine is currently blocked, then calling StopBgp will lead to a complete deadlock, as the connection goroutine will never close as it is trying to send to the queue, but the queue will not be read as the server goroutine is currently waiting for the connection goroutine to exit.
To correct this, a context has been added that gets passed to the connection goroutine. This is then checked in a new select statement on the connection queue which gets cancelled by tcpListener.Close() ensuring the goroutine exits correctly even if the queue is full.