Skip to content

Fix BGReader deadlock when stopping background reads#2502

Closed
sergeydobrodey wants to merge 1 commit into
jackc:masterfrom
sergeydobrodey:master
Closed

Fix BGReader deadlock when stopping background reads#2502
sergeydobrodey wants to merge 1 commit into
jackc:masterfrom
sergeydobrodey:master

Conversation

@sergeydobrodey

@sergeydobrodey sergeydobrodey commented Feb 10, 2026

Copy link
Copy Markdown

BGReader.Read could block forever if Stop() was called while the background goroutine was stuck in a read.

Read now falls back to direct reading when status is StatusStopping, not just StatusStopped.
Adds a unit test that reproduces the deadlock and verifies the fix.

Tests
go test ./pgconn/internal/bgreader -run TestBGReaderReadDoesNotWaitWhenStopping

Possible it's a fix for #2119

@jackc

jackc commented Feb 11, 2026

Copy link
Copy Markdown
Owner

I think a race condition would be possible with this change. BGReader is defined as concurrency safe, but there is no guarantee the underlying io.Reader is. With this change the underlying io.Reader can be used concurrently.

  1. BGReader.Start() is called. bgRead() is started in a goroutine and blocks on Read() from the underlying io.Reader.
  2. BGReader.Read() is called and execution waits at r.cond.Wait()
  3. BGReader.Stop() is called. This sets status to StatusStopping, but it does not stop the goroutine running bgRead().
  4. BGReader.Read() is called again. Because status is StatusStopping it also calls Read() from the underlying io.Reader.

In practice, this shouldn't happen, both because we don't call BGReader.Read() concurrently, and we only use it with net.Conn which is concurrency safe. However, I don't want to introduce a latent bug either.

@sergeydobrodey

Copy link
Copy Markdown
Author

Agree. I'll close this PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants