Merge 0.11->trunk
authorKim Alvefur <zash@zash.se>
Fri, 08 Jan 2021 23:56:27 +0100
changeset 11268 2cdcf55c6dd5
parent 11264 08b397c21805 (current diff)
parent 11267 1274deeab39a (diff)
child 11271 97077089f3c2
Merge 0.11->trunk
net/server_epoll.lua
util/stanza.lua
util/timer.lua
--- 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