lk.Thread

:finalize (s)

local lib = {type = 'lk.Thread'} local sched = sched lib.__index = lib lk.Thread = lib

local WeakValue = {__mode = 'v'}

setmetatable(lib, { __call = function(lib, func, at) local self = { co = coroutine.create(func), func = func, should_run = true, } setmetatable(self, lib) local wrap = { -- weak link to thread t = setmetatable({t = self}, WeakValue), } self.wrap = wrap self.finalizer = lk.Finalizer(function() sched:remove(wrap) end) sched:scheduleAt(at or 0, self.wrap) return self end })

-- The calling threads joins with this thread. if self.co then coroutine.yield('join', self) else -- ignore: dead thread end end

return self.should_run end

self.should_run = false if self.wrap.fd then sched:removeFd(self.wrap) end self.wrap.at = 0 self.co = nil end

self.should_run = false end

--- @internal. The scheduler asks this thread to resume other threads -- on finalization. if not self.joins then self.joins = setmetatable({}, WeakValue) end table.insert(self.joins, thread_wrap) end

if self.joins then for _, thread_wrap in ipairs(self.joins) do -- joined scheduler:scheduleAt(0, thread_wrap) end end end