diff options
author | Romain Forlot <romain.forlot@iot.bzh> | 2019-01-18 13:37:12 +0100 |
---|---|---|
committer | Romain Forlot <romain.forlot@iot.bzh> | 2019-01-23 15:06:14 +0100 |
commit | 569a70213a52c5a0ba22c3a110c4b511d4574c83 (patch) | |
tree | d1f0f17c0513cd4af976a4f696245bd266d00f41 /conf.d/controller/lua.d/aft.lua | |
parent | 7582a430b719f2f22dc6312f5e464e7e7b834ba3 (diff) |
Handle event in core binding
Prefers to handle the events reception by the binding, in C, rather than using
the LUA interpreter to avoid race condition on the LUA context. Because we are
waiting events in LUA context using binder call sync, when the event is received
then 2 threads operate simultaneously on LUA context, the waiting event thread and
the receiving event thread.
Bug-AGL: SPEC-2135
Change-Id: Ied0a78a61263b8fd41305969c636a491c6bb0295
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
Diffstat (limited to 'conf.d/controller/lua.d/aft.lua')
-rw-r--r-- | conf.d/controller/lua.d/aft.lua | 88 |
1 files changed, 37 insertions, 51 deletions
diff --git a/conf.d/controller/lua.d/aft.lua b/conf.d/controller/lua.d/aft.lua index 971f8be..da51a18 100644 --- a/conf.d/controller/lua.d/aft.lua +++ b/conf.d/controller/lua.d/aft.lua @@ -135,55 +135,25 @@ function _AFT.triggerEvtCallback(eventName) end end -function _AFT.bindingEventHandler(eventObj, uid) - local eventName = nil - local eventListeners = nil - local data = nil - - if uid then - eventName = uid - data = eventObj - elseif eventObj.event.name then - eventName = eventObj.event.name - eventListeners = eventObj.data.result - -- Remove from event to hold the bare event data and be able to assert it - eventObj.data.result = nil - data = eventObj.data.data - end - - if type(_AFT.monitored_events[eventName]) == 'table' then - local stopSync = true - if eventListeners then - _AFT.monitored_events[eventName].eventListeners = eventListeners +function _AFT.bindingEventHandler(eventObj) + local eventName = eventObj.event.name + if eventObj.data.result then + _AFT.monitored_events[eventName].eventListeners = eventObj.data.result + end + + _AFT.incrementCount(_AFT.monitored_events[eventName]) + _AFT.registerData(_AFT.monitored_events[eventName], + eventObj.data.data) + + for name,value in pairs(_AFT.monitored_events) do + if (_AFT.monitored_events[name].expected and + _AFT.monitored_events[name].receivedCount < _AFT.monitored_events[name].expected + ) + then + return true end - - _AFT.incrementCount(_AFT.monitored_events[eventName]) - _AFT.registerData(_AFT.monitored_events[eventName], data) - - for name,value in pairs(_AFT.monitored_events) do - if (_AFT.monitored_events[name].expected and - _AFT.monitored_events[name].receivedCount < _AFT.monitored_events[name].expected) - then - stopSync = false - end - end - - if stopSync == true and _AFT.waiting == true then - AFB:servsync(_AFT.context, _AFT.apiname, "sync", { stop = 1 }) - _AFT.waiting = false - end - end -end - -function _evt_catcher_(source, action, eventObj) - local uid = AFB:getuid(source) - if uid == "monitor/trace" then - if eventObj.type == "event" then - _AFT.bindingEventHandler(eventObj) - end - --else - -- _AFT.bindingEventHandler(eventObj, uid) end + return false end function _AFT.lockWait(eventName, timeout) @@ -192,12 +162,18 @@ function _AFT.lockWait(eventName, timeout) return 0 end - _AFT.waiting = true local err,responseJ = AFB:servsync(_AFT.context, _AFT.apiname, "sync", { start = timeout}) - if err then + if err or (not responseJ and not responseJ.response.event.name) then return 0 end + + _AFT.bindingEventHandler(responseJ.response) + + if AFB:servsync(_AFT.context, _AFT.apiname, "sync", {stop = true}) then + return 0 + end + return 1 end @@ -212,10 +188,20 @@ function _AFT.lockWaitGroup(eventGroup, timeout) _AFT.monitored_events[event].expected = expectedCount + _AFT.monitored_events[event].receivedCount end - _AFT.waiting = true + local waiting = true local err, responseJ = AFB:servsync(_AFT.context, _AFT.apiname, "sync", { start = timeout }) + while waiting do + if err or (not responseJ and not responseJ.response.event.name) then + return 0 + end + + waiting = _AFT.bindingEventHandler(responseJ.response) - if err then + if waiting == true then + err, responseJ = AFB:servsync(_AFT.context, _AFT.apiname, "sync", {continue = true}) + end + end + if AFB:servsync(_AFT.context, _AFT.apiname, "sync", {stop = true}) then return 0 end |