Skip to content

Commit 2c68129

Browse files
committed
tasklist: fix deadlocks
* lock correct resources * unlock list before queueing
1 parent 60f3eb1 commit 2c68129

1 file changed

Lines changed: 12 additions & 3 deletions

File tree

task/list.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,25 @@ func (list *List) consumer() {
7070
task.wgTask.Done()
7171
list.wg.Done()
7272

73+
unlocked := false
7374
for _, t := range list.tasks {
7475
if t.State == IDLE {
7576
// check resources
7677
blockingTasks := list.usedResources.UsedBy(t.resources)
7778
if len(blockingTasks) == 0 {
78-
list.usedResources.MarkInUse(task.resources, task)
79+
list.usedResources.MarkInUse(t.resources, t)
80+
// unlock list since queueing may block
81+
list.Unlock()
82+
unlocked = true
7983
list.queue <- t
8084
break
8185
}
8286
}
8387
}
88+
if !unlocked {
89+
list.Unlock()
90+
}
8491
}
85-
list.Unlock()
8692
}()
8793

8894
case <-list.queueDone:
@@ -187,7 +193,6 @@ func (list *List) GetTaskReturnValueByID(ID int) (*ProcessReturnValue, error) {
187193
// become available.
188194
func (list *List) RunTaskInBackground(name string, resources []string, process Process) (Task, *ResourceConflictError) {
189195
list.Lock()
190-
defer list.Unlock()
191196

192197
list.idCounter++
193198
wgTask := &sync.WaitGroup{}
@@ -204,7 +209,11 @@ func (list *List) RunTaskInBackground(name string, resources []string, process P
204209
tasks := list.usedResources.UsedBy(resources)
205210
if len(tasks) == 0 {
206211
list.usedResources.MarkInUse(task.resources, task)
212+
// queueing task might block if channel not ready, unlock list before queueing
213+
list.Unlock()
207214
list.queue <- task
215+
} else {
216+
list.Unlock()
208217
}
209218

210219
return *task, nil

0 commit comments

Comments
 (0)