From d46c43fbeb5e2fcc1d3cccf348ebb92f60f4bc2d Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 29 Nov 2021 14:14:30 +0000 Subject: util.async: Add next-tick configuration Running woken runners in the next iteration of the event loop prevents unexpected recursion, unexpected tracebacks, and is generally more predictable. The pattern is borrowed from util.promise, where we're now doing the same. --- util/async.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'util') diff --git a/util/async.lua b/util/async.lua index 551a5e5c..ece589cb 100644 --- a/util/async.lua +++ b/util/async.lua @@ -13,6 +13,9 @@ end -- Configurable functions local schedule_task = nil; -- schedule_task(seconds, callback) +local next_tick = function (f) + f(); +end local function runner_from_thread(thread) local level = 0; @@ -62,8 +65,10 @@ local function runner_continue(thread) -- If state is 'ready', it is our responsibility to update runner.state from 'waiting'. -- We also have to :run(), because the queue might have further items that will not be -- processed otherwise. FIXME: It's probably best to do this in a nexttick (0 timer). - runner.state = "ready"; - runner:run(); + next_tick(function () + runner.state = "ready"; + runner:run(); + end); end return true; end @@ -286,5 +291,6 @@ return { wait_for = wait_for; sleep = sleep; + set_nexttick = function(new_next_tick) next_tick = new_next_tick; end; set_schedule_function = function (new_schedule_function) schedule_task = new_schedule_function; end; }; -- cgit v1.2.3