net.server_epoll: Optimize away table allocation for timer objects

This commit is contained in:
Kim Alvefur 2020-06-29 20:23:59 +02:00
parent 2b81c3b50f
commit a1ae266ff7

View file

@ -86,22 +86,27 @@ local fds = createtable(10, 0); -- FD -> conn
local timers = indexedbheap.create(); local timers = indexedbheap.create();
local function noop() end local function noop() end
local function closetimer(t) local function closetimer(id)
t[1] = noop; timers:remove(id);
timers:remove(t.id);
end end
local function reschedule(t, time) local function reschedule(id, time)
time = monotonic() + time; time = monotonic() + time;
timers:reprioritize(t.id, time); timers:reprioritize(id, time);
end end
-- Add relative timer -- Add relative timer
local function addtimer(timeout, f, param) local function addtimer(timeout, f, param)
local time = monotonic() + timeout; local time = monotonic() + timeout;
local timer = { f, param, close = closetimer, reschedule = reschedule, id = nil }; if param ~= nil then
timer.id = timers:insert(timer, time); local timer_callback = f
return timer; function f(current_time, timer_id)
local t = timer_callback(current_time, timer_id, param)
return t;
end
end
local id = timers:insert(f, time);
return id;
end end
-- Run callbacks of expired timers -- Run callbacks of expired timers
@ -118,8 +123,8 @@ local function runtimers(next_delay, min_wait)
break; break;
end end
local _, timer = timers:pop(); local _, timer, id = timers:pop();
local ok, ret = pcall(timer[1], now, timer, timer[2]); local ok, ret = pcall(timer, now, id);
if ok and type(ret) == "number" then if ok and type(ret) == "number" then
local next_time = elapsed+ret; local next_time = elapsed+ret;
timers:insert(timer, next_time); timers:insert(timer, next_time);
@ -259,14 +264,14 @@ end
function interface:setreadtimeout(t) function interface:setreadtimeout(t)
if t == false then if t == false then
if self._readtimeout then if self._readtimeout then
self._readtimeout:close(); closetimer(self._readtimeout);
self._readtimeout = nil; self._readtimeout = nil;
end end
return return
end end
t = t or cfg.read_timeout; t = t or cfg.read_timeout;
if self._readtimeout then if self._readtimeout then
self._readtimeout:reschedule(t); reschedule(self._readtimeout, t);
else else
self._readtimeout = addtimer(t, function () self._readtimeout = addtimer(t, function ()
if self:on("readtimeout") then if self:on("readtimeout") then
@ -285,14 +290,14 @@ end
function interface:setwritetimeout(t) function interface:setwritetimeout(t)
if t == false then if t == false then
if self._writetimeout then if self._writetimeout then
self._writetimeout:close(); closetimer(self._writetimeout);
self._writetimeout = nil; self._writetimeout = nil;
end end
return return
end end
t = t or cfg.send_timeout; t = t or cfg.send_timeout;
if self._writetimeout then if self._writetimeout then
self._writetimeout:reschedule(t); reschedule(self._writetimeout, t);
else else
self._writetimeout = addtimer(t, function () self._writetimeout = addtimer(t, function ()
self:noise("Write timeout"); self:noise("Write timeout");
@ -663,7 +668,8 @@ end
function interface:pausefor(t) function interface:pausefor(t)
self:noise("Pause for %fs", t); self:noise("Pause for %fs", t);
if self._pausefor then if self._pausefor then
self._pausefor:close(); closetimer(self._pausefor);
self._pausefor = nil;
end end
if t == false then return; end if t == false then return; end
self:set(false); self:set(false);