package comsync
import (
"fmt"
"sync"
"time"
)
type Syncer struct {
locker sync.Mutex
maxRunner int
curRunner int
}
type Locker interface {
Add(inc int)
Done(del int)
Wait()
GetThread() int
}
func SyncerCreate(maxRunner int) *Syncer {
if maxRunner <= 0 {
return nil
}
var sx Syncer
sx.maxRunner = maxRunner
return &sx
}
func (m *Syncer) Add(x int) bool {
if x <= 0 {
return true
}
if x > m.maxRunner {
panic(fmt.Sprintf("Syncer %d is larger than max value %d", x, m.maxRunner))
return false
}
for true {
if add(m, x) {
return true
}
time.Sleep(time.Microsecond * 100)
}
return true
}
func add(m *Syncer, x int) bool {
m.locker.Lock()
defer m.locker.Unlock()
if m.curRunner+x > m.maxRunner {
return false
}
m.curRunner += x
return true
}
func (m *Syncer) Done(x int) {
if x <= 0 {
return
}
m.locker.Lock()
defer m.locker.Unlock()
m.curRunner -= x
if m.curRunner < 0 {
m.curRunner = 0
}
return
}
func (m *Syncer) Wait() {
for true {
if m.curRunner <= 0 {
return
}
time.Sleep(time.Microsecond * 10)
}
return
}
func (m *Syncer) GetThread() int {
return m.curRunner
}