summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-03-13 14:37:48 -0400
committerNat Goodspeed <nat@lindenlab.com>2024-03-13 14:37:48 -0400
commit354d7b55c0a267b542dc51e3985f7d3739ffcdfd (patch)
tree7d1c401b89d8c292cfc691bdfed9b4d380ce58e6 /indra
parent587d65dc127fd72cd72aed5f02dbfd3bf277a9ef (diff)
Introduce a resume() wrapper to surface coroutine errors.
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/scripts/lua/qtest.lua25
1 files changed, 20 insertions, 5 deletions
diff --git a/indra/newview/scripts/lua/qtest.lua b/indra/newview/scripts/lua/qtest.lua
index 12e425b7b2..009446d0c3 100644
--- a/indra/newview/scripts/lua/qtest.lua
+++ b/indra/newview/scripts/lua/qtest.lua
@@ -7,6 +7,19 @@ util = require('util')
inspect = require('inspect')
+-- resume() wrapper to propagate errors
+function 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
+
-- ------------------ Queue variables are instance-specific ------------------
q1 = Queue:new()
q2 = Queue:new()
@@ -51,9 +64,9 @@ coa = coroutine.create(consumer)
cob = coroutine.create(consumer)
-- Since consumer() doesn't yield while it can still retrieve values,
-- consumer(a) will dequeue all values from q1 and return when done.
-coroutine.resume(coa, 'a', q1)
+resume(coa, 'a', q1)
-- consumer(b) will wake up to find the queue empty and closed.
-coroutine.resume(cob, 'b', q1)
+resume(cob, 'b', q1)
coroutine.close(coa)
coroutine.close(cob)
@@ -72,7 +85,7 @@ for _, name in {'a', 'b'} do
local coro = coroutine.create(consumer)
table.insert(coros, coro)
-- Resuming both coroutines should leave them both waiting for a queue item.
- coroutine.resume(coro, name, q3)
+ resume(coro, name, q3)
end
for _, s in pairs(values) do
@@ -89,6 +102,8 @@ function joinall(coros)
for i, coro in pairs(coros) do
if coroutine.status(coro) == 'suspended' then
running = true
+ -- directly call coroutine.resume() instead of our resume()
+ -- wrapper because we explicitly check for errors here
local ok, message = coroutine.resume(coro)
if not ok then
print('*** ' .. message)
@@ -105,7 +120,7 @@ end
joinall(coros)
-print(string.format('%q', util.join(result, ' ')))
+print(string.format('%q', table.concat(result, ' ')))
assert(util.equal(values, result))
-- ----------------------------- test ErrorQueue -----------------------------
@@ -118,7 +133,7 @@ for _, name in {'a', 'b'} do
local coro = coroutine.create(consumer)
table.insert(coros, coro)
-- Resuming both coroutines should leave them both waiting for a queue item.
- coroutine.resume(coro, name, q4)
+ resume(coro, name, q4)
end
for i = 1, 4 do