1 Star 0 Fork 0

zjh-tech / go-etimer

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
timermgr.go 3.09 KB
一键复制 编辑 原始数据 按行查看 历史
zjh-tech 提交于 2023-08-02 13:40 . init
package etimer
import (
"container/list"
)
type TimerMgr struct {
uid uint64
slotList [MaxSlotSize]*list.List
curSlot uint64
lastTick int64
}
func NewTimerMgr() *TimerMgr {
mgr := &TimerMgr{
curSlot: 0,
uid: 0,
}
for i := uint64(0); i < MaxSlotSize; i++ {
mgr.slotList[i] = list.New()
}
mgr.lastTick = getMillSecond()
return mgr
}
func (t *TimerMgr) Run() {
curMillSecond := getMillSecond()
if curMillSecond < t.lastTick {
ELog.Error("[Timer] Time Rollback")
return
}
delta := curMillSecond - t.lastTick
t.lastTick += delta
for i := int64(0); i < delta; i++ {
t.curSlot++
t.curSlot = t.curSlot % MaxSlotSize
slotList := t.slotList[t.curSlot]
var next *list.Element
repeat_list := list.New()
for e := slotList.Front(); e != nil; {
next = e.Next()
timer := e.Value.(*Timer)
if timer.state != TimerRunningState {
t.ReleaseTimer(timer)
slotList.Remove(e)
e = next
continue
}
timer.rotation--
if timer.rotation < 0 {
ELog.Debugf("[Timer] Trigger Id %v-%v", timer.uid, timer.eid)
slotList.Remove(e)
timer.Call()
if timer.repeat && timer.state == TimerRunningState {
repeat_list.PushBack(timer) //先加入repeatList,防止此循环又被遍历到
} else {
t.ReleaseTimer(timer)
}
} else {
ELog.Debugf("[Timer] Id=%v-%v Remain Rotation=%v MaxSlotSize=%v", timer.uid, timer.eid, timer.rotation+1, MaxSlotSize)
}
e = next
}
if repeat_list.Len() != 0 {
for e := repeat_list.Front(); e != nil; e = e.Next() {
timer := e.Value.(*Timer)
//不考虑timer.Call花费的时间,不然会有逻辑顺序问题
t.AddSlotTimer(timer)
}
}
}
}
func (t *TimerMgr) UnInit() {
}
func (t *TimerMgr) CreateSlotTimer(eid uint32, delay uint64, repeat bool, cb FuncType, args ArgType, r *TimerRegister) *Timer {
t.uid++
timer := newTimer(eid, t.uid, delay, repeat, cb, args, r)
return timer
}
func (t *TimerMgr) AddSlotTimer(timer *Timer) {
if timer == nil {
return
}
timer.state = TimerRunningState
timer.rotation = int64(timer.delay / MaxSlotSize)
timer.slot = (t.curSlot + timer.delay%MaxSlotSize) % MaxSlotSize
tempRotation := timer.rotation
if timer.slot == t.curSlot && timer.rotation > 0 {
timer.rotation--
}
t.slotList[timer.slot].PushBack(timer)
ELog.Debugf("[Timer] AddSlotTimer Id=%v-%v Delay=%v,Curslot=%v,Slot=%v,Rotation=%v", timer.uid, timer.eid, timer.delay, t.curSlot, timer.slot, tempRotation)
}
func (t *TimerMgr) ReleaseTimer(timer *Timer) {
if timer != nil {
if timer.state == TimerRunningState {
ELog.Debugf("[Timer] ReleaseTimer Id=%v-%v Running State", timer.uid, timer.eid)
} else if timer.state == TimerKilledState {
ELog.Debugf("[Timer] ReleaseTimer Id=%v-%v Killed State", timer.uid, timer.eid)
} else {
ELog.Debugf("[Timer] ReleaseTimer Id=%v-%v Unknow State", timer.uid, timer.eid)
}
timer.cb = nil
timer.args = nil
if timer.register != nil {
timer.register.RemoveTimer(timer)
timer.register = nil
}
}
}
func (t *TimerMgr) GetCurSlot() uint64 {
return t.curSlot
}
var GTimerMgr *TimerMgr
func init() {
GTimerMgr = NewTimerMgr()
}
Go
1
https://gitee.com/zjh-tech/go-etimer.git
git@gitee.com:zjh-tech/go-etimer.git
zjh-tech
go-etimer
go-etimer
master

搜索帮助