From 3f844fccaf188101388e8129eef5328a7bfa21c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=9C=E6=AC=A2?= Date: Fri, 20 Sep 2024 06:11:39 +0800 Subject: [PATCH] Fix pool.go : exists p.workerCount > p.cap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit step 1 : p.WorkerCount() < atomic.LoadInt32(&p.cap) step 2 : p.incWorkerCount()  step 1 + step 2 not atomic operation , causing the worker count to exceed the cap  So Fix to atomic.CompareAndSwapInt32 --- util/gopool/pool.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/util/gopool/pool.go b/util/gopool/pool.go index 276cc3f5..dc68a1e6 100644 --- a/util/gopool/pool.go +++ b/util/gopool/pool.go @@ -130,11 +130,13 @@ func (p *pool) CtxGo(ctx context.Context, f func()) { // 1. the number of tasks is greater than the threshold. // 2. The current number of workers is less than the upper limit p.cap. // or there are currently no workers. - if (atomic.LoadInt32(&p.taskCount) >= p.config.ScaleThreshold && p.WorkerCount() < atomic.LoadInt32(&p.cap)) || p.WorkerCount() == 0 { - p.incWorkerCount() - w := workerPool.Get().(*worker) - w.pool = p - w.run() + workerCount := p.WorkerCount() + if (atomic.LoadInt32(&p.taskCount) >= p.config.ScaleThreshold && workerCount < atomic.LoadInt32(&p.cap)) || workerCount == 0 { + if atomic.CompareAndSwapInt32(&p.workerCount, workerCount, workerCount+1) { + w := workerPool.Get().(*worker) + w.pool = p + w.run() + } } }