serveConn dispatched under context.Background(), so a dispatch in flight
during shutdown could not be told to stop and closeGrace could only
abandon it. The server now carries a context, Close cancels it, and each
conn derives its own so nothing outlives the connection.
A zero-value Server built outside Listen falls back to Background; two
wiring tests do that.
Client.Close read c.conn with no lock while roundtrip re-dialed and
dropped it, which -race caught on the new test. The conn field now has
its own mutex, held only across a read or an assignment, so Close and
the watchdog reach the connection without queueing behind the call they
are interrupting.
roundtrip set no connection deadline and call checked the context once,
before sending, so a daemon that read the frame and stopped answering
parked the caller for as long as the socket stayed open.
The deadline comes from the caller's context, falling back to 120s, the
convention internal/voice/client.go already had. A watchdog closes the
conn on ctx.Done(); it closes rather than calling drop, because drop
wants c.mu and call is holding it.
The retry split is unchanged and now also declines a retry the caller
has stopped waiting for. A cancelled mutation stays ErrAmbiguousOutcome,
because it may have committed. A cancelled read reports the cancellation.
Three tests against a server that accepts and never answers. There was
no test for this, which is why it went unnoticed.