| 46 | } |
| 47 | |
| 48 | func (q *TaskQueue) Pop() (types.Task, bool) { |
| 49 | q.mu.Lock() |
| 50 | defer q.mu.Unlock() |
| 51 | |
| 52 | for len(q.tasks) == q.head && !q.done { |
| 53 | q.idleWorkers.Add(1) |
| 54 | q.waiting.Add(1) |
| 55 | q.cond.Wait() |
| 56 | q.waiting.Add(-1) |
| 57 | q.idleWorkers.Add(-1) |
| 58 | } |
| 59 | |
| 60 | if len(q.tasks) == q.head { |
| 61 | return types.Task{}, false |
| 62 | } |
| 63 | |
| 64 | t := q.tasks[q.head] |
| 65 | q.head++ |
| 66 | q.size.Add(-1) |
| 67 | if q.head > len(q.tasks)/2 { |
| 68 | |
| 69 | // slice instead of copy to avoid allocation |
| 70 | q.tasks = q.tasks[q.head:] |
| 71 | q.head = 0 |
| 72 | } |
| 73 | return t, true |
| 74 | } |
| 75 | |
| 76 | func (q *TaskQueue) Close() { |
| 77 | q.mu.Lock() |