Hi, I was looking at mu.lock and had a question about this part:
func (m *mu) lock(ctx context.Context) error {
select {
case <-m.c.closed:
return net.ErrClosed
case <-ctx.Done():
return fmt.Errorf("failed to acquire lock: %w", ctx.Err())
case m.ch <- struct{}{}:
// To make sure the connection is certainly alive.
// As it's possible the send on m.ch was selected
// over the receive on closed.
select {
case <-m.c.closed:
// Make sure to release.
m.unlock()
return net.ErrClosed
default:
}
return nil
}
}
After acquiring the lock, closed is checked again in case both branches were ready.
Why isn't ctx.Done() checked here as well?
Could ctx be canceled right after m.ch is selected, causing lock to return nil while holding the lock with an already-canceled context?
Hi, I was looking at mu.lock and had a question about this part:
After acquiring the lock,
closedis checked again in case both branches were ready.Why isn't
ctx.Done()checked here as well?Could
ctxbe canceled right afterm.chis selected, causinglockto returnnilwhile holding the lock with an already-canceled context?