aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-01-08 23:23:56 +0100
committerKim Alvefur <zash@zash.se>2021-01-08 23:23:56 +0100
commita7c018ed86c937b86d2f25cd868a05628bba82d8 (patch)
tree56b05b903152fb1fd608b41bf7ba7cfb80ee5b8c
parentnet.server_epoll: Ensure timers can't run more than once per tick (diff)
downloadprosody-a7c018ed86c937b86d2f25cd868a05628bba82d8.tar.xz
prosody-a7c018ed86c937b86d2f25cd868a05628bba82d8.zip
util.timer: Ensure timers can't run more than once per tick (fixes #1620)
See longer explanation in 2c559953ad41
-rw-r--r--util/timer.lua15
1 files changed, 14 insertions, 1 deletions
diff --git a/util/timer.lua b/util/timer.lua
index 4670e196f..bc3836be5 100644
--- a/util/timer.lua
+++ b/util/timer.lua
@@ -15,6 +15,7 @@ local debug_traceback = debug.traceback;
local tostring = tostring;
local xpcall = require "util.xpcall".xpcall;
local math_max = math.max;
+local pairs = pairs;
local _ENV = nil;
-- luacheck: std none
@@ -29,6 +30,7 @@ local next_time = nil;
local function _traceback_handler(err) log("error", "Traceback[timer]: %s", debug_traceback(tostring(err), 2)); end
local function _on_timer(now)
local peek;
+ local readd;
while true do
peek = h:peek();
if peek == nil or peek > now then break; end
@@ -38,11 +40,22 @@ local function _on_timer(now)
--item(now, id, _param);
local success, err = xpcall(callback, _traceback_handler, now, id, param);
if success and type(err) == "number" then
- h:insert(callback, err + now, id); -- re-add
+ if readd then
+ readd[id] = { callback, err + now };
+ else
+ readd = { [id] = { callback, err + now } };
+ end
params[id] = param;
end
end
+ if readd then
+ for id,timer in pairs(readd) do
+ h:insert(timer[1], timer[2], id);
+ end
+ peek = h:peek();
+ end
+
if peek ~= nil and _active_timers > 1 and peek == next_time then
-- Another instance of _on_timer already set next_time to the same value,
-- so it should be safe to not renew this timer event