From 861e5125c7e8fcb92cd7d00c5a3ebbfa8f149933 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 8 Jan 2021 21:57:19 +0100 Subject: 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 --- net/server_epoll.lua | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'net') 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 -- cgit v1.2.3