From a94755dbc57e9318578983c2199d7e61ff5dbe01 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Mon, 20 Nov 2017 22:13:34 -0800 Subject: [PATCH] fix deadlock in bitswap sessions This deadlock would happen when calling SessionsForBlock (holding bitswap.sessLk) while the session's main loop was trying to deregister the session (taking bitswap.sessLk). I've also defensively added selects on contexts for two other channel writes just in case. fixes #4394 ...well, it fixes *a* deadlock showing up in that issue, there may be more. License: MIT Signed-off-by: Steven Allen --- exchange/bitswap/session.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/exchange/bitswap/session.go b/exchange/bitswap/session.go index 987ab30f686..9c7f85b300f 100644 --- a/exchange/bitswap/session.go +++ b/exchange/bitswap/session.go @@ -120,9 +120,13 @@ type interestReq struct { // still be in the interest cache. func (s *Session) isLiveWant(c *cid.Cid) bool { resp := make(chan bool, 1) - s.interestReqs <- interestReq{ + select { + case s.interestReqs <- interestReq{ c: c, resp: resp, + }: + case <-s.ctx.Done(): + return false } select { @@ -278,13 +282,17 @@ func (s *Session) cancel(keys []*cid.Cid) { } func (s *Session) cancelWants(keys []*cid.Cid) { - s.cancelKeys <- keys + select { + case s.cancelKeys <- keys: + case <-s.ctx.Done(): + } } func (s *Session) fetch(ctx context.Context, keys []*cid.Cid) { select { case s.newReqs <- keys: case <-ctx.Done(): + case <-s.ctx.Done(): } }