--- a/net/server_epoll.lua Fri Jan 08 17:32:06 2021 +0100
+++ b/net/server_epoll.lua Fri Jan 08 23:56:27 2021 +0100
@@ -119,10 +119,10 @@
local elapsed = monotonic();
local now = realtime();
local peek = timers:peek();
+ local readd;
while peek do
if peek > elapsed then
- next_delay = peek - elapsed;
break;
end
@@ -130,15 +130,31 @@
local ok, ret = xpcall(timer, traceback, now, id);
if ok and type(ret) == "number" then
local next_time = elapsed+ret;
- 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, next_time };
+ else
+ readd = { [id] = { timer, next_time } };
+ end
elseif not ok then
log("error", "Error in timer: %s", ret);
end
peek = timers:peek();
end
+
+ if readd then
+ for _, timer in pairs(readd) do
+ timers:insert(timer[1], timer[2]);
+ end
+ peek = timers:peek();
+ end
+
if peek == nil then
return next_delay;
+ else
+ next_delay = peek - elapsed;
end
if next_delay < min_wait then
--- a/util/stanza.lua Fri Jan 08 17:32:06 2021 +0100
+++ b/util/stanza.lua Fri Jan 08 23:56:27 2021 +0100
@@ -66,9 +66,9 @@
local function check_text(text, text_type)
if type(text) ~= "string" then
error("invalid "..text_type.." value: expected string, got "..type(text));
- elseif not valid_xml_cdata(text) then
+ elseif not valid_xml_cdata(text, false) then
error("invalid "..text_type.." value: contains control characters");
- elseif not valid_utf8(text, false) then
+ elseif not valid_utf8(text) then
error("invalid "..text_type.." value: contains invalid utf8");
end
end
--- a/util/timer.lua Fri Jan 08 17:32:06 2021 +0100
+++ b/util/timer.lua Fri Jan 08 23:56:27 2021 +0100
@@ -15,6 +15,7 @@
local tostring = tostring;
local xpcall = require "util.xpcall".xpcall;
local math_max = math.max;
+local pairs = pairs;
if server.timer then
-- The selected net.server implements this API, so defer to that
@@ -34,6 +35,7 @@
local function _traceback_handler(err) log("error", "Traceback[timer]: %s", debug_traceback(tostring(err), 2)); end
local function _on_timer(now)
local peek;
+ local readd;
while true do
peek = h:peek();
if peek == nil or peek > now then break; end
@@ -43,11 +45,22 @@
--item(now, id, _param);
local success, err = xpcall(callback, _traceback_handler, now, id, param);
if success and type(err) == "number" then
- h:insert(callback, err + now, id); -- re-add
+ if readd then
+ readd[id] = { callback, err + now };
+ else
+ readd = { [id] = { callback, err + now } };
+ end
params[id] = param;
end
end
+ if readd then
+ for id,timer in pairs(readd) do
+ h:insert(timer[1], timer[2], id);
+ end
+ peek = h:peek();
+ end
+
if peek ~= nil and _active_timers > 1 and peek == next_time then
-- Another instance of _on_timer already set next_time to the same value,
-- so it should be safe to not renew this timer event