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.

221 lines
4.1 KiB
Go

/*
****************************
struct Event
****************************
실제 이벤트 데이터
Copy()
이벤트 데이터 복사
****************************
struct EventH
****************************
struct Event 핸들링 구조체. singleton이며 전역 변수.
struct Event를 array로 가진다.
AllocEvent()
array에서 빈 event item을 확보하고 데이터를 넣는다.
RemoveEvent()
array에서 해당 event를 삭제.
PostEvent()
이벤트를 받을 세션에 이벤트를 보낸다.
GetEvent()
이벤트 수신.
polling 방식
*/
package icsevent
import (
"sync"
"gitlab.com/cinnamon/voiceagent/icserror"
)
const (
MAX_EVENT_NUM = 65536
//MAX_EVENT_NUM = 655360
MAX_CHANNEL_NUM = 256
)
///////////////////////////////////////////////////////////////
// 단위 이벤트
type Event struct {
Data *interface{}
ID int
//m *sync.Mutex
}
func (e *Event) GetData() *interface{} {
return e.Data
}
///////////////////////////////////////////////////////////////
// 전역 이벤트 배열
type EventH struct {
evtArray []*Event
m *sync.Mutex
}
var eventData []*Event
var onceEvent sync.Once
var onceEventInit sync.Once
var channelNum int = MAX_CHANNEL_NUM
var eventNum int = MAX_EVENT_NUM
var lastPos int
func getEventInstance() []*Event {
onceEvent.Do(func() {
eventData = make([]*Event, eventNum)
for iter := 0; iter < eventNum; iter++ {
eventData[iter] = new(Event)
//eventData[iter].m = &sync.Mutex{}
}
lastPos = 0
})
return eventData
}
//make global Event Array
func NewEventH() *EventH {
//s := icssvc.NewService()
//channelNum = s.GetIcsConfig().GetChannelNum()
//TODO: add recover
h := &EventH{}
h.evtArray = getEventInstance()
h.m = &sync.Mutex{}
return h
}
//initialize Event Array
func (h *EventH) Init() {
onceEventInit.Do(func() {
for iter := 0; iter < eventNum; iter++ {
h.evtArray[iter].Data = nil
h.evtArray[iter].ID = iter
}
})
}
//put data to event array
func (h *EventH) AllocEvent(data interface{}) (*Event, *icserror.IcsError) {
count := 0
for iter := lastPos; count < eventNum; iter++ {
if iter == eventNum {
iter = 0
}
//h.evtArray[iter].m.Lock()
h.m.Lock()
if h.evtArray[iter].Data == nil {
h.evtArray[iter].Data = &data
lastPos = iter + 1
//h.evtArray[iter].m.Unlock()
h.m.Unlock()
return h.evtArray[iter], nil
}
//h.evtArray[iter].m.Unlock()
h.m.Unlock()
count++
}
return nil, icserror.ICSERREVTAlloc
}
//remove data from Event Array
func (h *EventH) RemoveEvent(event *Event) *icserror.IcsError {
if event == nil {
return icserror.ICSERRInvalidParam
}
if h.evtArray[event.ID].Data == nil {
return icserror.ICSERREVTRemove
}
//h.evtArray[event.ID].m.Lock()
h.m.Lock()
h.evtArray[event.ID].Data = nil
//h.evtArray[event.ID].m.Unlock()
h.m.Unlock()
return nil
}
func (h *EventH) removeEvent(id int) *icserror.IcsError {
if h.evtArray[id].Data == nil {
return icserror.ICSERREVTRemove
}
//h.evtArray[id].m.Lock()
h.m.Lock()
h.evtArray[id].Data = nil
//h.evtArray[id].m.Unlock()
h.m.Unlock()
return nil
}
func (h *EventH) Copy(src *Event, dst *Event) *icserror.IcsError {
if dst == nil {
return icserror.ICSERRInvalidParam
}
//e.m.Lock()
h.m.Lock()
dst.Data = src.Data
dst.ID = src.ID
h.m.Unlock()
//e.m.Unlock()
return nil
}
func (h *EventH) PostEvent(targetID int, event *Event) *icserror.IcsError {
if targetID < 0 || event == nil {
return icserror.ICSERRInvalidParam
}
target := GetEvtSystemInstance()
q := target[targetID]
esErr := q.PutJob(event)
if esErr != nil {
return esErr
}
return nil
}
func (h *EventH) GetEvent(targetID int) (*Event, *icserror.IcsError) {
if targetID < 0 {
return nil, icserror.ICSERRInvalidParam
}
target := GetEvtSystemInstance()
q := target[targetID]
pos, esErr := q.GetJob()
if esErr != nil || pos < 0 {
return nil, esErr
}
e := &Event{}
//h.evtArray[pos].Copy(e)
h.Copy(h.evtArray[pos], e)
h.RemoveEvent(h.evtArray[pos])
return e, nil
}
//FOR ONLY DEBUG. DO NOT USE THIS FUNCTION-getEvt()!
func (h *EventH) getEvt(eventID int) *Event {
return h.evtArray[eventID]
}