summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-03-13 14:31:05 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-03-13 14:31:05 -0400
commit587d65dc127fd72cd72aed5f02dbfd3bf277a9ef (patch)
treed7711d4cd2a21f54481f07af2ada2185a7958b9f /indra/newview
parentc371096fc3320f580fd271dad09c852f2e3d5f78 (diff)
Make a coro.resume() wrapper and use in coro.launch(), coro.yield().
coro.resume() checks the ok boolean returned by coroutine.resume() and, if not ok, propagates the error. This avoids coroutine errors getting swallowed.
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/scripts/lua/coro.lua24
1 files changed, 17 insertions, 7 deletions
diff --git a/indra/newview/scripts/lua/coro.lua b/indra/newview/scripts/lua/coro.lua
index 8f868f5a48..616a797e95 100644
--- a/indra/newview/scripts/lua/coro.lua
+++ b/indra/newview/scripts/lua/coro.lua
@@ -5,15 +5,25 @@ local coro = {}
coro._coros = {}
-- Launch a Lua coroutine: create and resume.
--- Returns:
--- new coroutine
--- bool ok
--- if not ok: error message
--- if ok: values yielded or returned
+-- Returns: new coroutine, values yielded or returned from initial resume()
+-- If initial resume() encountered an error, propagates the error.
function coro.launch(func, ...)
local co = coroutine.create(func)
table.insert(coro._coros, co)
- return co, coroutine.resume(co, ...)
+ return co, coro.resume(co, ...)
+end
+
+-- resume() wrapper to propagate errors
+function coro.resume(co, ...)
+ -- if there's an idiom other than table.pack() to assign an arbitrary
+ -- number of return values, I don't yet know it
+ local ok_result = table.pack(coroutine.resume(co, ...))
+ if not ok_result[1] then
+ -- if [1] is false, then [2] is the error message
+ error(ok_result[2])
+ end
+ -- ok is true, whew, just return the rest of the values
+ return table.unpack(ok_result, 2)
end
-- yield to other coroutines even if you don't know whether you're in a
@@ -28,7 +38,7 @@ function coro.yield(...)
-- Walk a copy of coro._coros in case any of these coroutines launches
-- another: next() forbids creating new entries during traversal.
for co in coro._live_coros_iter, table.clone(coro._coros) do
- co.resume()
+ coro.resume(co)
end
end
end