gammazero / workerpool

Concurrency limiting goroutine pool
MIT License
1.33k stars 138 forks source link

Race between Submit and Stop #76

Open AnshulMalik opened 4 months ago

AnshulMalik commented 4 months ago

Submit() tries to send message to taskQueue

func (p *WorkerPool) Submit(task func()) {
    if task != nil {
        p.taskQueue <- task
    }
}

https://github.com/gammazero/workerpool/blob/master/workerpool.go#L109

stop() closes the taskQueue.

func (p *WorkerPool) stop(wait bool) {
    p.stopOnce.Do(func() {
        // Signal that workerpool is stopping, to unpause any paused workers.
        close(p.stopSignal)
        // Acquire stopLock to wait for any pause in progress to complete. All
        // in-progress pauses will complete because the stopSignal unpauses the
        // workers.
        p.stopLock.Lock()
        // The stopped flag prevents any additional paused workers. This makes
        // it safe to close the taskQueue.
        p.stopped = true
        p.stopLock.Unlock()
        p.wait = wait
        // Close task queue and wait for currently running tasks to finish.
        close(p.taskQueue)
    })
    <-p.stoppedChan
}

Both of these can be happening in separate goroutines, and it can trigger a panic of writing to a closed chan.