110 lines
2.2 KiB
Go
110 lines
2.2 KiB
Go
package f5
|
|
|
|
import (
|
|
"q5"
|
|
"sync"
|
|
)
|
|
|
|
type MsgHandler struct {
|
|
deleted bool
|
|
entry q5.ListHead
|
|
cb func(q5.Args)
|
|
}
|
|
|
|
type msgQueue struct {
|
|
msgHandlers [256] struct {
|
|
lock sync.Mutex
|
|
head q5.ListHead
|
|
delingLock sync.Mutex
|
|
delingHandlers []*MsgHandler
|
|
addingLock sync.Mutex
|
|
addingHead q5.ListHead
|
|
}
|
|
}
|
|
|
|
func (this *msgQueue) init() {
|
|
for i := 0; i < len(this.msgHandlers); i++ {
|
|
node := &this.msgHandlers[i]
|
|
node.lock.Lock()
|
|
node.head.Init(nil)
|
|
node.lock.Unlock()
|
|
|
|
node.addingLock.Lock()
|
|
node.addingHead.Init(nil)
|
|
node.addingLock.Unlock()
|
|
}
|
|
}
|
|
|
|
func (this *msgQueue) unInit() {
|
|
|
|
}
|
|
|
|
func (this *msgQueue) RegisterCb(msgId int, cb func(q5.Args)) *MsgHandler {
|
|
if msgId >= len(this.msgHandlers) {
|
|
panic("msgQueue.msgId error")
|
|
}
|
|
p := new(MsgHandler)
|
|
p.cb = cb
|
|
p.entry.Init(p)
|
|
node := &this.msgHandlers[msgId]
|
|
node.addingLock.Lock()
|
|
defer node.addingLock.Unlock()
|
|
node.addingHead.AddTail(&p.entry)
|
|
return p
|
|
}
|
|
|
|
func (this *msgQueue) UnRegisterCb(handler *MsgHandler) {
|
|
if handler != nil {
|
|
handler.deleted = true
|
|
}
|
|
}
|
|
|
|
func (this *msgQueue) FireEvent(msgId int, args q5.Args) {
|
|
if msgId < 0 || msgId >= len(this.msgHandlers) {
|
|
return
|
|
}
|
|
node := &this.msgHandlers[msgId]
|
|
node.lock.Lock()
|
|
defer node.lock.Unlock()
|
|
node.head.ForEach(
|
|
func (data interface{}) bool {
|
|
h := data.(*MsgHandler)
|
|
if !h.deleted {
|
|
h.cb(args)
|
|
} else {
|
|
node.delingLock.Lock()
|
|
q5.AppendSlice(&node.delingHandlers, h)
|
|
node.delingLock.Unlock()
|
|
}
|
|
return true
|
|
})
|
|
this.clearNode(&node.delingLock, &node.delingHandlers)
|
|
node.addingLock.Lock()
|
|
defer node.addingLock.Unlock()
|
|
if !node.addingHead.Empty() {
|
|
node.addingHead.ForEach(
|
|
func (data interface{}) bool {
|
|
h := data.(*MsgHandler)
|
|
h.entry.DelInit()
|
|
if !h.deleted {
|
|
node.head.AddTail(&h.entry)
|
|
h.cb(args)
|
|
} else {
|
|
node.delingLock.Lock()
|
|
q5.AppendSlice(&node.delingHandlers, h)
|
|
node.delingLock.Unlock()
|
|
}
|
|
return true
|
|
})
|
|
}
|
|
this.clearNode(&node.delingLock, &node.delingHandlers)
|
|
}
|
|
|
|
func (this *msgQueue) clearNode(delingLock *sync.Mutex, delingHandlers *[]*MsgHandler) {
|
|
delingLock.Lock()
|
|
defer delingLock.Unlock()
|
|
if len(*delingHandlers) > 0 {
|
|
*delingHandlers = []*MsgHandler{}
|
|
}
|
|
}
|