You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
naza/pkg/taskpool/pool.go

72 lines
1.4 KiB
Go

// Copyright 2019, Chef. All rights reserved.
// https://github.com/q191201771/naza
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package taskpool
import (
"container/list"
"sync"
"sync/atomic"
)
type pool struct {
idleWorkerNum int32
busyWorkerNum int32
//m SpinLock
m sync.Mutex
idleWorkerList *list.List
}
func (p *pool) Go(task Task) {
var w *Worker
p.m.Lock()
e := p.idleWorkerList.Front()
if e != nil {
w = e.Value.(*Worker)
p.idleWorkerList.Remove(e)
atomic.AddInt32(&p.idleWorkerNum, -1)
atomic.AddInt32(&p.busyWorkerNum, 1)
}
p.m.Unlock()
if w == nil {
w = NewWorker(p)
w.Start()
atomic.AddInt32(&p.busyWorkerNum, 1)
}
w.Go(task)
}
func (p *pool) KillIdleWorkers() {
p.m.Lock()
n := p.idleWorkerList.Len()
var next *list.Element
for e := p.idleWorkerList.Front(); e != nil; e = next {
w := e.Value.(*Worker)
w.Stop()
next = e.Next()
p.idleWorkerList.Remove(e)
}
atomic.AddInt32(&p.idleWorkerNum, int32(-n))
p.m.Unlock()
}
func (p *pool) Status() (idleWorkerNum int, busyWorkerNum int) {
idleWorkerNum = int(atomic.LoadInt32(&p.idleWorkerNum))
busyWorkerNum = int(atomic.LoadInt32(&p.busyWorkerNum))
return
}
func (p *pool) markIdle(w *Worker) {
p.m.Lock()
atomic.AddInt32(&p.idleWorkerNum, 1)
atomic.AddInt32(&p.busyWorkerNum, -1)
p.idleWorkerList.PushBack(w)
p.m.Unlock()
}