From: Matthias Kruk Date: Sat, 24 Apr 2021 05:25:15 +0000 (+0900) Subject: include/queue: Add queue_foreach() function X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=ae7f6924c6bd2a266570af58d03b3dafbaf13aa1;p=toolbox include/queue: Add queue_foreach() function 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 --- diff --git a/include/queue.sh b/include/queue.sh index 29a93e3..8962e3a 100644 --- a/include/queue.sh +++ b/include/queue.sh @@ -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 +}