From 8dbfee7bb5da380cb6c32c0650bf42c260aad56b 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 987ab30f6865..9c7f85b300f6 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(): } }