From 066fc4b78458c0fa7241e5820573863cc6545424 Mon Sep 17 00:00:00 2001 From: payonel Date: Thu, 21 Sep 2017 13:49:16 +0200 Subject: [PATCH] protect dispatch from callbacks that unregister handlers closes #2528 --- .../opencomputers/loot/openos/lib/event.lua | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua b/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua index 5e59e6e72..b34ce0287 100644 --- a/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua +++ b/src/main/resources/assets/opencomputers/loot/openos/lib/event.lua @@ -42,25 +42,26 @@ computer.pullSignal = function(...) -- dispatch end local event_data = table.pack(handlers(...)) local signal = event_data[1] - local ids = {} - for id in pairs(handlers) do - ids[#ids+1] = id + local copy = {} + for id,handler in pairs(handlers) do + copy[id] = handler end - for _,id in ipairs(ids) do - local handler = handlers[id] + for id,handler in pairs(copy) do -- timers have false keys -- nil keys match anything if (handler.key == nil or handler.key == signal) or current_time >= handler.timeout then handler.times = handler.times - 1 handler.timeout = current_time + handler.interval - if handler.times <= 0 then + -- we have to remove handlers before making the callback in case of timers that pull + -- and we have to check handlers[id] == handler because callbacks may have unregistered things + if handler.times <= 0 and handlers[id] == handler then handlers[id] = nil end -- call local result, message = pcall(handler.callback, table.unpack(event_data, 1, event_data.n)) if not result then pcall(event.onError, message) - elseif message == false then + elseif message == false and handlers[id] == handler then handlers[id] = nil end end