coroutine pool in parallel code

This commit is contained in:
kepler155c@gmail.com
2019-04-05 21:47:35 -04:00
parent 426c856dfb
commit 5f2f33f1f2

View File

@@ -1,8 +1,31 @@
local class = require('class')
local parallel = _G.parallel
local os = _G.os
local TaskRunner = class()
local free = { }
local function createTask(fn)
local task = table.remove(free)
if not task then
task = {
fn = fn,
co = coroutine.create(function()
local args = { }
while true do
pcall(task.fn, table.unpack(args))
task.dead = true
table.insert(free, task)
args = { coroutine.yield() }
end
end)
}
else
task.dead = nil
task.fn = fn
end
return task
end
function TaskRunner:init(args)
self.tasks = { }
@@ -14,17 +37,30 @@ function TaskRunner:init(args)
end
function TaskRunner:add(fn)
table.insert(self.tasks, function()
local s, m = pcall(fn)
if not s and m then
self:onError(m)
end
end)
table.insert(self.tasks, createTask(fn))
end
function TaskRunner:run()
if #self.tasks > 0 then
parallel.waitForAll(table.unpack(self.tasks))
local event = { }
while #self.tasks > 0 do
for n = #self.tasks, 1, -1 do
local task = self.tasks[n]
if task.filter == nil or task.filter == event[1] or event[1] == "terminate" then
local ok, param = coroutine.resume(task.co, table.unpack(event))
if not ok then
self:onError(param)
else
task.filter = param
end
if task.dead then
table.remove(self.tasks, n)
end
end
end
event = { os.pullEventRaw() }
end
end
end