diff options
author | gVisor bot <gvisor-bot@google.com> | 2021-02-25 02:21:36 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-25 02:21:36 +0000 |
commit | 66545e7a77b8bfc97e3b12b61ff50f90e81fe880 (patch) | |
tree | d659d03bdd17f109db999c3c9a6f9707d3ea3c71 | |
parent | 66780c3d858b2e7902aac87ed9a25c7e79a381e8 (diff) | |
parent | 0462dfe9f8bfbe482912caeb2bd636ec005b2b9e (diff) |
Merge release-20210208.0-94-g0462dfe9f (automated)
-rw-r--r-- | pkg/p9/server.go | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/pkg/p9/server.go b/pkg/p9/server.go index 8c5c434fd..290d5b9ce 100644 --- a/pkg/p9/server.go +++ b/pkg/p9/server.go @@ -81,8 +81,8 @@ type connState struct { // version 0 implies 9P2000.L. version uint32 - // pendingWg counts requests that are still being handled. - pendingWg sync.WaitGroup + // reqGate counts requests that are still being handled. + reqGate sync.Gate // -- below relates to the legacy handler -- @@ -481,9 +481,13 @@ func (cs *connState) lookupChannel(id uint32) *channel { // handle handles a single message. func (cs *connState) handle(m message) (r message) { - cs.pendingWg.Add(1) + if !cs.reqGate.Enter() { + // connState.stop() has been called; the connection is shutting down. + r = newErr(syscall.ECONNRESET) + return + } defer func() { - cs.pendingWg.Done() + cs.reqGate.Leave() if r == nil { // Don't allow a panic to propagate. err := recover() @@ -594,10 +598,11 @@ func (cs *connState) handleRequests() { } func (cs *connState) stop() { - // Wait for completion of all inflight requests. This is mostly so that if - // a request is stuck, the sandbox supervisor has the opportunity to kill - // us with SIGABRT to get a stack dump of the offending handler. - cs.pendingWg.Wait() + // Stop new requests from proceeding, and wait for completion of all + // inflight requests. This is mostly so that if a request is stuck, the + // sandbox supervisor has the opportunity to kill us with SIGABRT to get a + // stack dump of the offending handler. + cs.reqGate.Close() // Free the channels. cs.channelMu.Lock() |