@cryptotaxi247 / kubo / commits / a94755dbc

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 <steven@stebalien.com>

Steven Allen committed Nov 20, 2017 at 22:13 UTC a94755dbc57e9318578983c2199d7e61ff5dbe01
1 file changed +10 -2
exchange/bitswap/session.go
+10 -2
@@ -120,9 +120,13 @@ type interestReq struct {
120 // still be in the interest cache.
121 func (s *Session) isLiveWant(c *cid.Cid) bool {
122 resp := make(chan bool, 1)
123 - s.interestReqs <- interestReq{
123 + select {
124 + case s.interestReqs <- interestReq{
125 c: c,
126 resp: resp,
127 + }:
128 + case <-s.ctx.Done():
129 + return false
130 }
131
132 select {
@@ -278,13 +282,17 @@ func (s *Session) cancel(keys []*cid.Cid) {
282 }
283
284 func (s *Session) cancelWants(keys []*cid.Cid) {
281 - s.cancelKeys <- keys
285 + select {
286 + case s.cancelKeys <- keys:
287 + case <-s.ctx.Done():
288 + }
289 }
290
291 func (s *Session) fetch(ctx context.Context, keys []*cid.Cid) {
292 select {
293 case s.newReqs <- keys:
294 case <-ctx.Done():
295 + case <-s.ctx.Done():
296 }
297 }
298