coder/websocket

websocket.Conn.CloseNow() panics in WaitGroup.Wait

tomasji opened this issue · 2 comments

nhooyr.io/websocket v1.8.10

When CloseNow() is called by 2 goroutines, there is a race condition:

panic: sync: WaitGroup is reused before previous Wait has returned

goroutine 105321 [running]:
sync.(*WaitGroup).Wait(0xe33400?)
	/src/sync/waitgroup.go:118 +0x74
nhooyr.io/websocket.(*Conn).CloseNow(0xc02d1e5860)
	/.go/pkg/mod/nhooyr.io/websocket@v1.8.10/close.go:113 +0xcb

Original func

func (c *Conn) CloseNow() (err error) {
	defer c.wg.Wait()
	defer errd.Wrap(&err, "failed to close WebSocket")

	if c.isClosed() {
		return net.ErrClosed
	}
...
}

Possible fix: move defer calls below isClosed()

func (c *Conn) CloseNow() (err error) {
	if c.isClosed() {
		return net.ErrClosed
	}
	defer c.wg.Wait()
	defer errd.Wrap(&err, "failed to close WebSocket")
...
}

Thanks for reporting. I've fixed this in #427. Please review and let me know if you see anything else.

Sorry for the delay. Fixed by #427.