Skip to content

fix: prevent deadlock in server Write and websocket Close/WriteManual#408

Open
rishabhvaish wants to merge 1 commit intolorenzodonini:masterfrom
rishabhvaish:fix/websocket-write-deadlock
Open

fix: prevent deadlock in server Write and websocket Close/WriteManual#408
rishabhvaish wants to merge 1 commit intolorenzodonini:masterfrom
rishabhvaish:fix/websocket-write-deadlock

Conversation

@rishabhvaish
Copy link
Copy Markdown

Summary

Fixes #291

server.Write held connMutex.RLock while calling webSocket.WriteManual, which held webSocket.mutex.RLock while sending on outQueue. If the channel buffer was full, the goroutine blocked holding both read locks. Concurrently, cleanup() needed both write locks — deadlock.

The fix releases each lock immediately after the map lookup / nil check, before any channel send. A deferred recover handles the race where cleanup() closes the channel between the nil check and the send.

Changes:

  • server.Write: release connMutex.RLock right after map lookup
  • webSocket.WriteManual: release mutex.RLock after nil check, add recover
  • webSocket.Close: same pattern as WriteManual

Test plan

  • go test ./ws/... -v -race passes
  • Verify concurrent writes + forced disconnects no longer freeze the server

🤖 Generated with Claude Code

The server's Write method held connMutex.RLock while calling
webSocket.Write, which in turn held webSocket.mutex.RLock while
sending on the outQueue channel. If the channel was full, the
goroutine blocked while holding both locks. Meanwhile, cleanup()
needed webSocket.mutex.Lock and handleDisconnect needed
connMutex.Lock, creating a deadlock.

The fix releases each lock immediately after the map/nil-check
lookup, before any potentially-blocking channel send. A deferred
recover guards against the race where cleanup closes the channel
between the nil check and the send.

Fixes lorenzodonini#291
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.

[ENG] help! websocket write: broken pipe, and ws.cleanupConnection() Unlock() not work

1 participant