Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions internal/pool/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,10 @@ type Conn struct {
bw *bufio.Writer
wr *proto.Writer

// Lightweight mutex to protect reader operations during handoff
// Only used for the brief period during SetNetConn and HasBufferedData/PeekReplyTypeSafe
// Lightweight mutex to protect reader operations during handoff and health checks
// Used during:
// - SetNetConn (write lock for resetting reader state)
// - HasBufferedData/PeekReplyTypeSafe (read lock for safe concurrent peek operations)
readerMu sync.RWMutex

// State machine for connection state management
Expand Down
14 changes: 12 additions & 2 deletions internal/pool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -1616,9 +1616,19 @@ func (p *ConnPool) Close() error {
// Check health before closing, since closeConn invalidates the
// underlying fd and would make connCheck (inside isHealthyConn)
// always fail with EBADF.
healthy := p.isHealthyConn(cn, nowNs)
// Only check health for idle connections to avoid data races when
// peeking at the socket/reader while another goroutine is reading from it.
// Non-idle connections are either in use or in transitional states and
// shouldn't be health-checked during shutdown.
_, isIdle := idleSet[cn.GetID()]
var healthy bool
if isIdle {
healthy = p.isHealthyConn(cn, nowNs)
} else {
healthy = true
}
if cb != nil {
if _, isIdle := idleSet[cn.GetID()]; isIdle {
if isIdle {
cb(ctx, -1, cn, "idle", false)
} else {
cb(ctx, -1, cn, "used", false)
Expand Down
Loading