/* **************************** 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/ics_cinnamon/voicegateway/icserror" ) const ( 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] }