-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparallel.lua
More file actions
45 lines (40 loc) · 1.42 KB
/
parallel.lua
File metadata and controls
45 lines (40 loc) · 1.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
local os = require "craftos.os"
local parallel = {}
local function run(fn, min)
local coros = {}
for i, v in ipairs(fn) do
if type(v) ~= "function" then error("bad argument #" .. i .. " (expected function, got " .. type(v) .. ")", 2) end
coros[i] = {coro = coroutine.create(v), filter = nil, pos = i}
end
local ev = {n = 0}
while #coros >= min do
local i = 1
while i < #coros do
if coros[i].filter == nil or coros[i].filter == ev[1] then
local args = ev
repeat
local res = table.pack(coros[i].coro(table.unpack(args, 1, args.n)))
if not res[1] then error(res[2], 0) end
if res[2] == "syscall" then args = table.pack(coroutine.yield(table.unpack(res, 1, res.n)))
else coros[i].filter = res[2] end
until res[2] ~= "syscall"
if coros[i]:status() == "dead" then
local n = coros[i].pos
table.remove(coros, i)
if #coros < min then return n end
i=i-1
end
end
i=i+1
end
ev = table.pack(os.pullEvent())
end
return 1 -- this should never be hit
end
function parallel.waitForAny(...)
return run({...}, select("#", ...))
end
function parallel.waitForAll(...)
return run({...}, 1)
end
return parallel