Commit c3d5b6ee authored by Brian Tiger Chow's avatar Brian Tiger Chow Committed by Juan Batiz-Benet

fix: add lock to taskQueue

@whyrusleeping may wanna have a look and make sure i didn't screw
anything up here

BenchmarkInstantaneousAddCat1MB-4            200          10763761 ns/op
97.42 MB/s
BenchmarkInstantaneousAddCat2MB-4       panic: runtime error: invalid
memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0xbedd]

goroutine 14297 [running]:
github.com/jbenet/go-ipfs/exchange/bitswap/decision.(*taskQueue).Remove(0xc2087553a0,
        0xc2085ef200, 0x22, 0x56f570, 0xc208367a40)
    /Users/btc/go/src/github.com/jbenet/go-ipfs/exchange/bitswap/decision/taskqueue.go:66
    +0x82
github.com/jbenet/go-ipfs/exchange/bitswap/decision.(*Engine).MessageSent(0xc20871b5c0,
        0x56f570, 0xc208367a40, 0x570040, 0xc208753d40, 0x0, 0x0)
    /Users/btc/go/src/github.com/jbenet/go-ipfs/exchange/bitswap/decision/engine.go:177
    +0x29e
github.com/jbenet/go-ipfs/exchange/bitswap.(*bitswap).send(0xc20871b7a0,
        0x56f4d8, 0xc208379800, 0x56f570, 0xc208367a40,
        0x570040, 0xc208753d40, 0x0, 0x0)
    /Users/btc/go/src/github.com/jbenet/go-ipfs/exchange/bitswap/bitswap.go:352
    +0x11c
github.com/jbenet/go-ipfs/exchange/bitswap.(*bitswap).taskWorker(0xc20871b7a0,
        0x56f4d8, 0xc208379800)
    /Users/btc/go/src/github.com/jbenet/go-ipfs/exchange/bitswap/bitswap.go:238
    +0x165
    created by
    github.com/jbenet/go-ipfs/exchange/bitswap.New
    /Users/btc/go/src/github.com/jbenet/go-ipfs/exchange/bitswap/bitswap.go:66
    +0x49e
parent 574213ff
package decision package decision
import ( import (
"sync"
wantlist "github.com/jbenet/go-ipfs/exchange/bitswap/wantlist" wantlist "github.com/jbenet/go-ipfs/exchange/bitswap/wantlist"
peer "github.com/jbenet/go-ipfs/peer" peer "github.com/jbenet/go-ipfs/peer"
u "github.com/jbenet/go-ipfs/util" u "github.com/jbenet/go-ipfs/util"
...@@ -11,6 +13,7 @@ import ( ...@@ -11,6 +13,7 @@ import (
// tasks (on getnext). For now, we are assuming a dumb/nice strategy. // tasks (on getnext). For now, we are assuming a dumb/nice strategy.
type taskQueue struct { type taskQueue struct {
// TODO: make this into a priority queue // TODO: make this into a priority queue
lock sync.Mutex
tasks []*task tasks []*task
taskmap map[string]*task taskmap map[string]*task
} }
...@@ -29,6 +32,8 @@ type task struct { ...@@ -29,6 +32,8 @@ type task struct {
// Push currently adds a new task to the end of the list // Push currently adds a new task to the end of the list
func (tl *taskQueue) Push(entry wantlist.Entry, to peer.Peer) { func (tl *taskQueue) Push(entry wantlist.Entry, to peer.Peer) {
tl.lock.Lock()
defer tl.lock.Unlock()
if task, ok := tl.taskmap[taskKey(to, entry.Key)]; ok { if task, ok := tl.taskmap[taskKey(to, entry.Key)]; ok {
// TODO: when priority queue is implemented, // TODO: when priority queue is implemented,
// rearrange this task // rearrange this task
...@@ -45,6 +50,8 @@ func (tl *taskQueue) Push(entry wantlist.Entry, to peer.Peer) { ...@@ -45,6 +50,8 @@ func (tl *taskQueue) Push(entry wantlist.Entry, to peer.Peer) {
// Pop 'pops' the next task to be performed. Returns nil no task exists. // Pop 'pops' the next task to be performed. Returns nil no task exists.
func (tl *taskQueue) Pop() *task { func (tl *taskQueue) Pop() *task {
tl.lock.Lock()
defer tl.lock.Unlock()
var out *task var out *task
for len(tl.tasks) > 0 { for len(tl.tasks) > 0 {
// TODO: instead of zero, use exponential distribution // TODO: instead of zero, use exponential distribution
...@@ -63,10 +70,12 @@ func (tl *taskQueue) Pop() *task { ...@@ -63,10 +70,12 @@ func (tl *taskQueue) Pop() *task {
// Remove lazily removes a task from the queue // Remove lazily removes a task from the queue
func (tl *taskQueue) Remove(k u.Key, p peer.Peer) { func (tl *taskQueue) Remove(k u.Key, p peer.Peer) {
tl.lock.Lock()
t, ok := tl.taskmap[taskKey(p, k)] t, ok := tl.taskmap[taskKey(p, k)]
if ok { if ok {
t.Trash = true t.Trash = true
} }
tl.lock.Unlock()
} }
// taskKey returns a key that uniquely identifies a task. // taskKey returns a key that uniquely identifies a task.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment