diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-08 10:12:37 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-08 10:12:37 +0300 |
| commit | 14995ca7a76e2a72a2169def7f55f3b9e2433ee2 (patch) | |
| tree | a4009a0dcc0473ec7cabf41f56312d8e8eeb1cc9 | |
| parent | d04a2b91fac52d5ff170b96f4f11846ddf7e01b8 (diff) | |
fix(gui): make GetActiveJobs concurrency-safe without channel access under lock
GetActiveJobs previously drained and refilled q.jobs while holding RLock,
racing with AddWordWithPrompt and ProcessNextJob on the same channel.
Derive queued jobs from q.results (StatusQueued) and processing jobs from
q.processing, matching the authoritative state already updated under the
mutex elsewhere.
Made-with: Cursor
| -rw-r--r-- | internal/gui/queue.go | 25 |
1 files changed, 8 insertions, 17 deletions
diff --git a/internal/gui/queue.go b/internal/gui/queue.go index 1646708..37b4b72 100644 --- a/internal/gui/queue.go +++ b/internal/gui/queue.go @@ -153,33 +153,24 @@ func (q *WordQueue) GetQueueStatus() (queued, processing, completed, failed int) return } -// GetActiveJobs returns all jobs that are currently queued or processing +// GetActiveJobs returns all jobs that are currently queued or processing. +// It uses only q.processing and q.results under the read lock; it does not +// touch q.jobs, because channel operations must not run while holding the +// mutex (other goroutines send/receive on q.jobs without the lock). func (q *WordQueue) GetActiveJobs() []*WordJob { q.mu.RLock() defer q.mu.RUnlock() var jobs []*WordJob - - // Add processing jobs for _, job := range q.processing { jobs = append(jobs, job) } - - // Add queued jobs from channel (non-blocking) - queuedJobs := make([]*WordJob, 0) - for { - select { - case job := <-q.jobs: - queuedJobs = append(queuedJobs, job) - default: - // Re-add jobs back to queue - for _, job := range queuedJobs { - q.jobs <- job - } - jobs = append(jobs, queuedJobs...) - return jobs + for _, job := range q.results { + if job.Status == StatusQueued { + jobs = append(jobs, job) } } + return jobs } // GetCompletedJobs returns all completed jobs |
