Added await and await_all, fixed bugs regarding event sending, added pool.byID
This commit is contained in:
parent
0f24eec42a
commit
eeb9433158
@ -1,37 +1,59 @@
|
|||||||
local mt = {}
|
local mt = {}
|
||||||
|
|
||||||
mt.newPool = function()
|
mt.newPool = function(pool_options)
|
||||||
|
pool_options = pool_options or {}
|
||||||
local pool = {}
|
local pool = {}
|
||||||
pool.threads = {} -- indexed by coroutines, contains their metadata
|
pool.threads = {} -- indexed by coroutines, contains their metadata
|
||||||
pool.namedThreads = {} -- indexed by coroutine names, contains their metadata also.
|
pool.namedThreads = {} -- indexed by coroutine names, contains their metadata also.
|
||||||
|
pool.byID = {} -- aaaa bees
|
||||||
-- coroutines are named if their metadata has a name field.
|
-- coroutines are named if their metadata has a name field.
|
||||||
pool.threadcount = 0 -- used for detecting when all things in a pool are depleted
|
pool.threadcount = 0 -- used for detecting when all things in a pool are depleted
|
||||||
|
pool.id = math.random(1,99999999999999)
|
||||||
pool.clear = function()
|
pool.clear = function()
|
||||||
pool.threads = {}
|
pool.threads = {}
|
||||||
pool.namedThreads = {}
|
pool.namedThreads = {}
|
||||||
pool.threadcount = 0
|
pool.threadcount = 0
|
||||||
end
|
end
|
||||||
|
local idcount = 0
|
||||||
|
|
||||||
pool.add = function(fn, options)
|
pool.add = function(fn, options)
|
||||||
options = options or {}
|
options = options or {}
|
||||||
options.co = coroutine.create(fn)
|
options.co = coroutine.create(function() local retv = fn(options) if retv~=nil then options.retv=retv end os.queueEvent("ignore_this") end)
|
||||||
|
options.fn = fn
|
||||||
|
options.id = idcount
|
||||||
|
idcount = idcount + 1
|
||||||
pool.threads[options.co] = options
|
pool.threads[options.co] = options
|
||||||
if options.name then
|
if options.name then
|
||||||
pool.namedThreads[options.name] = options
|
pool.namedThreads[options.name] = options
|
||||||
end
|
end
|
||||||
|
pool.byID[options.id] = options
|
||||||
pool.threadcount = pool.threadcount + 1
|
pool.threadcount = pool.threadcount + 1
|
||||||
os.queueEvent("pool_fn_added",options,pool)
|
os.queueEvent("pool_fn_added",options,pool)
|
||||||
return options.co
|
return options.co
|
||||||
end
|
end
|
||||||
|
|
||||||
pool.rm = function(name)
|
pool.rm = function(name)
|
||||||
|
local tr = nil
|
||||||
|
if type(name) == "string" then
|
||||||
if not pool.namedThreads[name] then
|
if not pool.namedThreads[name] then
|
||||||
return false
|
error("no thread with name "..name)
|
||||||
end
|
end
|
||||||
pool.threads[pool.namedThreads[name].co] = nil
|
tr = pool.namedThreads[name]
|
||||||
pool.namedThreads[name] = nil
|
elseif type(name)=="number" then
|
||||||
|
if not pool.byID[name] then
|
||||||
|
error("no thread with ID "..name)
|
||||||
|
end
|
||||||
|
tr = pool.byID[name]
|
||||||
|
else
|
||||||
|
tr = name
|
||||||
|
end
|
||||||
|
tr = pool.byID[tr.id]
|
||||||
|
os.queueEvent("pool_fn_end",tr.id,pool.id)
|
||||||
|
pool.threads[tr.co] = nil
|
||||||
|
if type(name)=="string" then pool.namedThreads[name] = nil end
|
||||||
|
pool.byID[name] = nil
|
||||||
pool.threadcount = pool.threadcount - 1
|
pool.threadcount = pool.threadcount - 1
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -52,23 +74,94 @@ mt.newPool = function()
|
|||||||
for thread, options in pairs(pool.threads) do
|
for thread, options in pairs(pool.threads) do
|
||||||
if coroutine.status(thread) ~= "dead" then
|
if coroutine.status(thread) ~= "dead" then
|
||||||
if event[1] == options.filter or options.filter == nil then
|
if event[1] == options.filter or options.filter == nil then
|
||||||
local x,e,y = pcall(coroutine.resume,thread,unpack(event))
|
local x,e,y = coroutine.resume(thread,unpack(event))
|
||||||
options.filter = y
|
options.filter = y
|
||||||
if not x then
|
if not x then
|
||||||
os.queueEvent("pool_fn_crash",e,options,pool)
|
os.queueEvent("pool_fn_crash",options.id,pool.id,e)
|
||||||
pool.threadcount = pool.threadcount - 1
|
pool.rm(options)
|
||||||
|
if pool_options.crash_on_error then
|
||||||
|
error(e)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
os.queueEvent("pool_fn_end",options,pool)
|
pool.rm(options)
|
||||||
pool.threadcount = pool.threadcount - 1
|
|
||||||
pool.threads[thread] = nil
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if pool.threadcount == 0 then return end
|
if pool.threadcount == 0 then return end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pool.await = function(...)
|
||||||
|
local args = {...}
|
||||||
|
local retv = {}
|
||||||
|
for i,v in ipairs(args) do
|
||||||
|
local to_match = nil
|
||||||
|
if type(v) == "table" then
|
||||||
|
to_match = v.id
|
||||||
|
elseif type(name)=="number" then
|
||||||
|
if not pool.byID[name] then
|
||||||
|
error("no thread with ID "..name)
|
||||||
|
end
|
||||||
|
to_match = name
|
||||||
|
else
|
||||||
|
if not pool.namedThreads[v] then
|
||||||
|
error("no thread named "..v)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
to_match = pool.namedThreads[v].id
|
||||||
|
end
|
||||||
|
if coroutine.status(pool.byID[to_match].co) == "dead" then
|
||||||
|
table.insert(retv, pool.byID[to_match].retv)
|
||||||
|
else
|
||||||
|
while true do
|
||||||
|
local e, b, c, d = os.pullEvent()
|
||||||
|
if (e=="pool_fn_end" or e=="pool_fn_crash") then
|
||||||
|
if c == pool.id and b == to_match then
|
||||||
|
table.insert(retv, pool.byID[b].retv)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return unpack(retv)
|
||||||
|
end
|
||||||
|
pool.await_any = function(...)
|
||||||
|
local args = {...}
|
||||||
|
local match = {}
|
||||||
|
for i,v in ipairs(args) do
|
||||||
|
local to_match = nil
|
||||||
|
if type(v) == "table" then
|
||||||
|
to_match = v.id
|
||||||
|
elseif type(name)=="number" then
|
||||||
|
if not pool.byID[name] then
|
||||||
|
error("no thread with ID "..name)
|
||||||
|
end
|
||||||
|
to_match = name
|
||||||
|
else
|
||||||
|
if not pool.namedThreads[v] then
|
||||||
|
error("no thread named "..v)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
to_match = pool.namedThreads[v].id
|
||||||
|
end
|
||||||
|
if coroutine.status(pool.byID[to_match].co) == "dead" then
|
||||||
|
return pool.byID[to_match].retv
|
||||||
|
end
|
||||||
|
table.insert(match,to_match)
|
||||||
|
end
|
||||||
|
while true do
|
||||||
|
local e, b, c, d = os.pullEvent()
|
||||||
|
if e=="pool_fn_end" and c == pool.id then
|
||||||
|
for i,v in ipairs(match) do
|
||||||
|
if b == v then
|
||||||
|
return pool.byID[v].retv
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
return pool
|
return pool
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
["version"] = "0.1.1",
|
["version"] = "0.1.2",
|
||||||
["dependencies"] = {},
|
["dependencies"] = {},
|
||||||
["description"] = "Adds convinientish multitasking functionality.",
|
["description"] = "Adds convinientish multitasking functionality.",
|
||||||
["files"] = {
|
["files"] = {
|
||||||
|
Loading…
Reference in New Issue
Block a user