tal/mod/core/evn-loop.lua

57 lines
1.2 KiB
Lua
Raw Normal View History

2025-02-06 00:30:52 +00:00
local resolver = require "lua-resolver";
local stack = array {};
2025-02-06 16:12:57 +00:00
local active_th, main_th;
2025-02-06 00:30:52 +00:00
local exports = {};
--- @param ... fun()
function exports.push(...)
stack:push(...);
end
function exports.interrupt()
2025-02-06 16:12:57 +00:00
if coro.running() == active_th then
2025-02-06 00:30:52 +00:00
-- We are trying to interrupt the currently active event loop thread
-- We will transfer away from it and "abandon" it (leave it for non-event loop use)
2025-02-06 16:12:57 +00:00
return coro.transfer(main_th);
2025-02-06 00:30:52 +00:00
else
-- We are currently in an abandoned or a non-loop thread. We can calmly transfer to the active thread
2025-02-06 16:12:57 +00:00
return coro.transfer(active_th);
2025-02-06 00:30:52 +00:00
end
end
--- @param main fun(...)
--- @param ... any
function exports.run(main, ...)
2025-02-06 16:12:57 +00:00
if active_th then
2025-02-06 00:30:52 +00:00
error "Event loop is already running!";
end
2025-02-06 16:12:57 +00:00
main_th = coro.running();
2025-02-06 00:30:52 +00:00
local args = box(...);
exports.push(function ()
main(unbox(args));
end)
while #stack > 0 do
2025-02-06 16:12:57 +00:00
active_th = coro.create(function ()
while #stack > 0 and coro.running() == active_th do
2025-02-06 00:30:52 +00:00
local msg = stack:shift();
msg();
end
2025-02-06 16:12:57 +00:00
coro.transfer(main_th);
2025-02-06 00:30:52 +00:00
end);
2025-02-06 16:12:57 +00:00
coro.transfer(active_th);
2025-02-06 00:30:52 +00:00
print "Abandoned thread...";
end
end
-- Register the module as phony
resolver.register("evn-loop.lua", exports);
return exports;