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