diff options
author | Kim Alvefur <zash@zash.se> | 2021-01-08 21:57:19 +0100 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2021-01-08 21:57:19 +0100 |
commit | a93c05e053a76e42a157db3e59e4e264dc5281a0 (patch) | |
tree | e31c0754b596fe524b5774be0661dd448ca7e26d /net/server_epoll.lua | |
parent | d6918df73ab0a487950d265b1bc9be4e495a248c (diff) | |
download | prosody-a93c05e053a76e42a157db3e59e4e264dc5281a0.tar.gz prosody-a93c05e053a76e42a157db3e59e4e264dc5281a0.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
Diffstat (limited to 'net/server_epoll.lua')
-rw-r--r-- | net/server_epoll.lua | 20 |
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 |