aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/server_epoll.lua20
-rw-r--r--util/stanza.lua4
-rw-r--r--util/timer.lua15
3 files changed, 34 insertions, 5 deletions
diff --git a/net/server_epoll.lua b/net/server_epoll.lua
index 010d1ca9..b079bdd2 100644
--- a/net/server_epoll.lua
+++ b/net/server_epoll.lua
@@ -119,10 +119,10 @@ local function runtimers(next_delay, min_wait)
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 function runtimers(next_delay, min_wait)
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
diff --git a/util/stanza.lua b/util/stanza.lua
index 85f047f8..3d4e9e5a 100644
--- a/util/stanza.lua
+++ b/util/stanza.lua
@@ -66,9 +66,9 @@ end
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
diff --git a/util/timer.lua b/util/timer.lua
index cbfc1992..84da02cf 100644
--- a/util/timer.lua
+++ b/util/timer.lua
@@ -15,6 +15,7 @@ local debug_traceback = debug.traceback;
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 next_time = nil;
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 @@ local function _on_timer(now)
--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