summaryrefslogtreecommitdiff
path: root/indra/newview/scripts/lua/ErrorQueue.lua
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2024-03-07 13:46:24 -0500
committerNat Goodspeed <nat@lindenlab.com>2024-03-07 13:46:24 -0500
commit63dcb3802c8139ff3b87b614cb275236cecea858 (patch)
tree121c5dc7a84c3df3b8cbcdd052c5d5cdf50ddab6 /indra/newview/scripts/lua/ErrorQueue.lua
parentc621fc39fc4ac25482fbc1090b8067c4187de176 (diff)
Finish WaitQueue, ErrorQueue; add util.count(), join(); extend qtest.
For WaitQueue, nail down the mechanism for declaring a subclass and for calling a base-class method from a subclass override. Break out new _wake_waiters() method from Enqueue(): we need to do the same from close(), in case there are waiting consumers. Also, in Lua, 0 is not false. Instead of bundling a normal/error flag with every queued value, make ErrorQueue overload its _closed attribute. Once you call ErrorQueue:Error(), every subsequent Dequeue() call by any consumer will re-raise the same error. util.count() literally counts entries in a table, since #t is documented to be unreliable. (If you create a list with 5 entries and delete the middle one, #t might return 2 or it might return 5, but it won't return 4.) util.join() fixes a curious omission from Luau's string library: like Python's str.join(), it concatenates all the strings from a list with an optional separator. We assume that incrementally building a list of strings and then doing a single allocation for the desired result string is cheaper than reallocating each of a sequence of partial concatenated results. Add qtest test that posts individual items to a WaitQueue, waking waiting consumers to retrieve the next available result. Add test proving that calling ErrorQueue:Error() propagates the error to all consumers.
Diffstat (limited to 'indra/newview/scripts/lua/ErrorQueue.lua')
-rw-r--r--indra/newview/scripts/lua/ErrorQueue.lua32
1 files changed, 15 insertions, 17 deletions
diff --git a/indra/newview/scripts/lua/ErrorQueue.lua b/indra/newview/scripts/lua/ErrorQueue.lua
index e6279f8411..db7022661e 100644
--- a/indra/newview/scripts/lua/ErrorQueue.lua
+++ b/indra/newview/scripts/lua/ErrorQueue.lua
@@ -1,32 +1,30 @@
-- ErrorQueue isa WaitQueue with the added feature that a producer can push an
--- error through the queue. When that error is dequeued, the consumer will
--- throw that error.
+-- error through the queue. Once that error is dequeued, every consumer will
+-- raise that error.
local WaitQueue = require('WaitQueue')
ErrorQueue = WaitQueue:new()
-function ErrorQueue:Enqueue(value)
- -- normal value, not error
- WaitQueue:Enqueue({ false, value })
-end
-
function ErrorQueue:Error(message)
- -- flag this entry as an error message
- WaitQueue:Enqueue({ true, message })
+ -- Setting Error() is a marker, like closing the queue. Once we reach the
+ -- error, every subsequent Dequeue() call will raise the same error.
+ self._closed = message
+ self:_wake_waiters()
end
function ErrorQueue:Dequeue()
- local errflag, value = table.unpack(WaitQueue:Dequeue())
- if errflag == nil then
- -- queue has been closed, tell caller
- return nil
+ local value = WaitQueue.Dequeue(self)
+ if value ~= nil then
+ -- queue not yet closed, show caller
+ return value
end
- if errflag then
- -- 'value' is a message pushed by Error()
- error(value)
+ if self._closed == true then
+ -- WaitQueue:close() sets true: queue has only been closed, tell caller
+ return nil
end
- return value
+ -- self._closed is a message set by Error()
+ error(self._closed)
end
return ErrorQueue