Comparison

net/server_epoll.lua @ 10985:758ce12586de

net.server_epoll: Optimize away table allocation for timer objects
author Kim Alvefur <zash@zash.se>
date Mon, 29 Jun 2020 20:23:59 +0200
parent 10984:69ed4764edda
child 10987:62355b801772
comparison
equal deleted inserted replaced
10984:69ed4764edda 10985:758ce12586de
84 -- Timer and scheduling -- 84 -- Timer and scheduling --
85 85
86 local timers = indexedbheap.create(); 86 local timers = indexedbheap.create();
87 87
88 local function noop() end 88 local function noop() end
89 local function closetimer(t) 89 local function closetimer(id)
90 t[1] = noop; 90 timers:remove(id);
91 timers:remove(t.id); 91 end
92 end 92
93 93 local function reschedule(id, time)
94 local function reschedule(t, time)
95 time = monotonic() + time; 94 time = monotonic() + time;
96 timers:reprioritize(t.id, time); 95 timers:reprioritize(id, time);
97 end 96 end
98 97
99 -- Add relative timer 98 -- Add relative timer
100 local function addtimer(timeout, f, param) 99 local function addtimer(timeout, f, param)
101 local time = monotonic() + timeout; 100 local time = monotonic() + timeout;
102 local timer = { f, param, close = closetimer, reschedule = reschedule, id = nil }; 101 if param ~= nil then
103 timer.id = timers:insert(timer, time); 102 local timer_callback = f
104 return timer; 103 function f(current_time, timer_id)
104 local t = timer_callback(current_time, timer_id, param)
105 return t;
106 end
107 end
108 local id = timers:insert(f, time);
109 return id;
105 end 110 end
106 111
107 -- Run callbacks of expired timers 112 -- Run callbacks of expired timers
108 -- Return time until next timeout 113 -- Return time until next timeout
109 local function runtimers(next_delay, min_wait) 114 local function runtimers(next_delay, min_wait)
116 if peek > elapsed then 121 if peek > elapsed then
117 next_delay = peek - elapsed; 122 next_delay = peek - elapsed;
118 break; 123 break;
119 end 124 end
120 125
121 local _, timer = timers:pop(); 126 local _, timer, id = timers:pop();
122 local ok, ret = pcall(timer[1], now, timer, timer[2]); 127 local ok, ret = pcall(timer, now, id);
123 if ok and type(ret) == "number" then 128 if ok and type(ret) == "number" then
124 local next_time = elapsed+ret; 129 local next_time = elapsed+ret;
125 timers:insert(timer, next_time); 130 timers:insert(timer, next_time);
126 end 131 end
127 132
257 262
258 -- Timeout for detecting dead or idle sockets 263 -- Timeout for detecting dead or idle sockets
259 function interface:setreadtimeout(t) 264 function interface:setreadtimeout(t)
260 if t == false then 265 if t == false then
261 if self._readtimeout then 266 if self._readtimeout then
262 self._readtimeout:close(); 267 closetimer(self._readtimeout);
263 self._readtimeout = nil; 268 self._readtimeout = nil;
264 end 269 end
265 return 270 return
266 end 271 end
267 t = t or cfg.read_timeout; 272 t = t or cfg.read_timeout;
268 if self._readtimeout then 273 if self._readtimeout then
269 self._readtimeout:reschedule(t); 274 reschedule(self._readtimeout, t);
270 else 275 else
271 self._readtimeout = addtimer(t, function () 276 self._readtimeout = addtimer(t, function ()
272 if self:on("readtimeout") then 277 if self:on("readtimeout") then
273 self:noise("Read timeout handled"); 278 self:noise("Read timeout handled");
274 return cfg.read_timeout; 279 return cfg.read_timeout;
283 288
284 -- Timeout for detecting dead sockets 289 -- Timeout for detecting dead sockets
285 function interface:setwritetimeout(t) 290 function interface:setwritetimeout(t)
286 if t == false then 291 if t == false then
287 if self._writetimeout then 292 if self._writetimeout then
288 self._writetimeout:close(); 293 closetimer(self._writetimeout);
289 self._writetimeout = nil; 294 self._writetimeout = nil;
290 end 295 end
291 return 296 return
292 end 297 end
293 t = t or cfg.send_timeout; 298 t = t or cfg.send_timeout;
294 if self._writetimeout then 299 if self._writetimeout then
295 self._writetimeout:reschedule(t); 300 reschedule(self._writetimeout, t);
296 else 301 else
297 self._writetimeout = addtimer(t, function () 302 self._writetimeout = addtimer(t, function ()
298 self:noise("Write timeout"); 303 self:noise("Write timeout");
299 self:on("disconnect", self._connected and "write timeout" or "connection timeout"); 304 self:on("disconnect", self._connected and "write timeout" or "connection timeout");
300 self:destroy(); 305 self:destroy();
661 666
662 -- Pause connection for some time 667 -- Pause connection for some time
663 function interface:pausefor(t) 668 function interface:pausefor(t)
664 self:noise("Pause for %fs", t); 669 self:noise("Pause for %fs", t);
665 if self._pausefor then 670 if self._pausefor then
666 self._pausefor:close(); 671 closetimer(self._pausefor);
672 self._pausefor = nil;
667 end 673 end
668 if t == false then return; end 674 if t == false then return; end
669 self:set(false); 675 self:set(false);
670 self._pausefor = addtimer(t, function () 676 self._pausefor = addtimer(t, function ()
671 self._pausefor = nil; 677 self._pausefor = nil;