diff --git a/cli.go b/cli.go index c5f4dc3..2b422f9 100644 --- a/cli.go +++ b/cli.go @@ -3,6 +3,7 @@ package manager import ( "context" "log" + "sync" "git.godopu.net/lab/etri-smartfarm-poc-controller-serial/puserial" "github.com/rjeczalik/notify" @@ -21,13 +22,15 @@ func init() { devWithUUID := map[string]*_device{} devWithIface := map[interface{}]*_device{} chanForSync := map[string]chan map[string]interface{}{} + var mutex = sync.Mutex{} _managerObj = &_manager{ devicesWithUUID: devWithUUID, devicesWithIface: devWithIface, chanForSync: chanForSync, - SyncListener: &SyncHandler{devices: devWithUUID, chanForSync: chanForSync}, - RecvListener: &RecvHandler{devices: devWithIface, chanForSync: chanForSync}, + mutex: &mutex, + SyncListener: &SyncHandler{devices: devWithUUID, chanForSync: chanForSync, mutex: &mutex}, + RecvListener: &RecvHandler{devices: devWithIface, chanForSync: chanForSync, mutex: &sync.Mutex{}}, } registerHandleFunc = nil diff --git a/listener.go b/listener.go index d1a3643..f2e5fb2 100644 --- a/listener.go +++ b/listener.go @@ -4,10 +4,12 @@ import ( "encoding/json" "fmt" "log" + "sync" ) type SyncHandler struct { devices map[string]*_device + mutex *sync.Mutex chanForSync map[string]chan map[string]interface{} } @@ -67,8 +69,10 @@ func (sh *SyncHandler) Handle(e Event) { _, ok := sh.chanForSync[device.IfaceName] if ok { + sh.mutex.Lock() close(sh.chanForSync[device.IfaceName]) delete(sh.chanForSync, device.IfaceName) + sh.mutex.Lock() } chanForSync := make(chan map[string]interface{}) sh.chanForSync[device.IfaceName] = make(chan map[string]interface{}) @@ -76,23 +80,26 @@ func (sh *SyncHandler) Handle(e Event) { for state := range chanForSync { if compareMap(origin, state) { + sh.mutex.Lock() close(sh.chanForSync[device.IfaceName]) delete(sh.chanForSync, device.IfaceName) + sh.mutex.Lock() return } log.Println("wrong: ", state) log.Println("resend: ", origin) err := encoder.Encode(origin) if err != nil { - log.Println("sync routine is died") return } } + log.Println("sync routine is died") }() } type RecvHandler struct { devices map[interface{}]*_device + mutex *sync.Mutex chanForSync map[string]chan map[string]interface{} next EventHandler } @@ -110,7 +117,9 @@ func (rh *RecvHandler) Handle(e Event) { } device.states = param + rh.mutex.Lock() channel, ok := rh.chanForSync[device.IfaceName] + rh.mutex.Unlock() if ok { channel <- device.states } diff --git a/manager.go b/manager.go index 0fa71a4..cd410c5 100644 --- a/manager.go +++ b/manager.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "log" + "sync" "github.com/jacobsa/go-serial/serial" ) @@ -14,6 +15,7 @@ type _manager struct { devicesWithUUID map[string]*_device devicesWithIface map[interface{}]*_device chanForSync map[string]chan map[string]interface{} + mutex *sync.Mutex RegisterListener EventHandler SyncListener EventHandler RecvListener EventHandler @@ -127,5 +129,5 @@ func (m *_manager) onRecv(key interface{}, params map[string]interface{}) { } func (m *_manager) addRecvListener(h EventHandler) { - m.RecvListener = &RecvHandler{next: h, devices: m.devicesWithIface, chanForSync: m.chanForSync} + m.RecvListener = &RecvHandler{next: h, devices: m.devicesWithIface, chanForSync: m.chanForSync, mutex: m.mutex} }