packages1/multitask/lib/multitask.lua

75 lines
1.8 KiB
Lua

local mt = {}
mt.newPool = function()
local pool = {}
pool.threads = {}
pool.namedThreads = {}
pool.threadcount = 0
pool.clear = function()
pool.threads = {}
pool.namedThreads = {}
pool.threadcount = 0
end
pool.add = function(fn, options)
options = options or {}
options.co = coroutine.create(fn)
pool.threads[options.co] = options
if options.name then
pool.namedThreads[options.name] = options
end
pool.threadcount = pool.threadcount + 1
os.queueEvent("pool_fn_added",options,pool)
return options.co
end
pool.rm = function(name)
if not pool.namedThreads[name] then
return false
end
pool.threads[pool.namedThreads[name].co] = nil
pool.namedThreads[name] = nil
pool.threadcount = pool.threadcount - 1
return true
end
pool.addFile = function(filename, options)
pool.add(function()
dofile(filename)
end,options)
end
pool.run = function(terminable)
terminable = terminable or true -- if false, terminate events will be echoed to coroutines instead of
-- terminating this pool
while true do
local event = {coroutine.yield()}
if event[1] == "terminate" and terminable then
return
end
for thread, options in pairs(pool.threads) do
if coroutine.status(thread) ~= "dead" then
if event[1] == options.filter or options.filter == nil then
local x,e,y = pcall(coroutine.resume,thread,unpack(event))
options.filter = y
if not x then
os.queueEvent("pool_fn_crash",e,options,pool)
pool.threadcount = pool.threadcount - 1
end
end
else
os.queueEvent("pool_fn_end",options,pool)
pool.threadcount = pool.threadcount - 1
pool.threads[thread] = nil
end
end
if pool.threadcount == 0 then return end
end
end
return pool
end
return mt