]> git.corax.cc Git - toolbox/commitdiff
include/queue: Add queue_foreach() function
authorMatthias Kruk <m@m10k.eu>
Sat, 24 Apr 2021 05:25:15 +0000 (14:25 +0900)
committerMatthias Kruk <m@m10k.eu>
Sun, 25 Apr 2021 05:09:42 +0000 (14:09 +0900)
There is currently no way to inspect the state of a queue, making it
very hard to write scripts that safely show the contents of a queue.
This commit adds the queue_foreach() function, which allows the caller
to invoke a callback function for each item in a queue.
The queue_foreach() function must be passed at least two arguments,
the name of the queue and the name of the callback function. All other
arguments will be passed on to the callback function.
If the callback returns a non-zero value, the iteration of the queue
will be aborted.
The queue_foreach() function will lock the queue for the duration that
the callbacks are executed. The callbacks must under absolutely no
circumstances attempt to perform any queue operations on the queue or
otherwise attempt to modify the queue, since this will either result
in a deadlock or leave the queue in an inconsistent state.

Example use:

    callback() {
        local item="$1"
        local user_data="$2"
        local more_data="$3"

        echo "$item:$user_data:$more_data"
        return 0
    }

    queue_init "someq"
    queue_put "someq" "hoge"
    queue_put "someq" "foobar"

    queue_foreach "someq" callback "the second argument" \
                                   "the third argument"

This will result in the following output.

    hoge:the second argument:the third argument
    foobar:the second argument:the third argument

include/queue.sh

index 29a93e39b0c1be346823fa4cc0079787abfdd47f..8962e3a3b1108a9ac4a75c6edba0c7ca597d8eb6 100644 (file)
@@ -43,7 +43,7 @@
 # The queue is implemented as a directory like this:
 #
 #  queue/
-#   |- lock
+#   |- mutex
 #   |- sem
 #   '- data
 #
@@ -453,3 +453,32 @@ queue_get_file() {
        echo "$dest"
        return 0
 }
+
+queue_foreach() {
+       local name="$1"
+       local func="$2"
+       local args=("${@:3}")
+
+       local data
+       local mutex
+       local item
+
+       data=$(_queue_get_data "$name")
+       mutex=$(_queue_get_mutex "$name")
+
+       if ! mutex_lock "$mutex"; then
+               return 1
+       fi
+
+       if [ -f "$data" ]; then
+               while read -r item; do
+                       if ! "$func" "$item" "${args[@]}"; then
+                               break
+                       fi
+               done < "$data"
+       fi
+
+       mutex_unlock "$mutex"
+
+       return 0
+}