aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Alvefur <zash@zash.se>2021-01-08 21:57:19 +0100
committerKim Alvefur <zash@zash.se>2021-01-08 21:57:19 +0100
commit1bf1a1ba69271ee169e6766d56dbef66aa980830 (patch)
treee31c0754b596fe524b5774be0661dd448ca7e26d
parent24e57b75900452b4172d666e9eee3592265cfcd6 (diff)
downloadprosody-1bf1a1ba69271ee169e6766d56dbef66aa980830.tar.gz
prosody-1bf1a1ba69271ee169e6766d56dbef66aa980830.zip
net.server_epoll: Ensure timers can't run more than once per tick
This makes sure that a timer that returns 0 (or less) does not prevent runtimers() from completing, as well as making sure a timer added with zero timeout from within a timer does not run until the next tick. Thanks tmolitor
-rw-r--r--net/server_epoll.lua20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/server_epoll.lua b/net/server_epoll.lua
index 953bbb11..e2be448c 100644
--- a/net/server_epoll.lua
+++ b/net/server_epoll.lua
@@ -97,10 +97,10 @@ local function runtimers(next_delay, min_wait)
-- Any timers at all?
local now = gettime();
local peek = timers:peek();
+ local readd;
while peek do
if peek > now then
- next_delay = peek - now;
break;
end
@@ -109,13 +109,29 @@ local function runtimers(next_delay, min_wait)
if ok and type(ret) == "number" then
local next_time = now+ret;
timer[1] = next_time;
- timers:insert(timer, next_time);
+ -- Delay insertion of timers to be re-added
+ -- so they don't get called again this tick
+ if readd then
+ readd[id] = timer;
+ else
+ readd = { [id] = timer };
+ end
end
peek = timers:peek();
end
+
+ if readd then
+ for _, timer in pairs(readd) do
+ timers:insert(timer, timer[2]);
+ end
+ peek = timers:peek();
+ end
+
if peek == nil then
return next_delay;
+ else
+ next_delay = peek - now;
end
if next_delay < min_wait then