]> git.corax.cc Git - toolbox/commitdiff
include/{mutex,wmutex,sem,queue}: Add timeout argument to blocking functions
authorMatthias Kruk <matthias.kruk@miraclelinux.com>
Sat, 29 May 2021 04:17:48 +0000 (13:17 +0900)
committerMatthias Kruk <matthias.kruk@miraclelinux.com>
Sat, 29 May 2021 04:32:03 +0000 (13:32 +0900)
The following functions potentially block the executing script indefinitely,
without a way to recover from the situation.
 - queue_get()
 - queue_get_file()
 - sem_wait()
 - mutex_lock()
 - wmutex_lock()

It is a common pattern to implement deamons dispatching messages from a queue
in the following way using the "inst" module.

    while inst_running; do
        local msg

        if msg=$(queue_get "$queue"); then
            handle_message "$msg"
        fi
    done

The problem with this code is that queue_get() potentially waits indefinitely,
and the daemon won't terminate even if it was instructed to. To mitigate this
situation, this commit adds a timeout argument to all of the above functions,
allowing the caller to specify the number of seconds the functions should wait
at most. If the timeout parameter is 0 or omitted, the functions will wait
forever (as is the current behavior), so existing code that uses any of the
above functions and that wishes to retain the current behavior does not need to
be modified.

include/mutex.sh
include/queue.sh
include/sem.sh
include/wmutex.sh

index c05652fde402c6f84263c17a9315c23ba3b01c8c..4efd9055c7d7d495af5c0d4a0be037a23a15c215 100644 (file)
@@ -21,6 +21,7 @@ mutex_trylock() {
 
 mutex_lock() {
        local lock="$1"
+       local -i timeout="$2"
 
        while ! mutex_trylock "$lock"; do
                # We can't inotifywait on symlinks. Which is
@@ -28,7 +29,7 @@ mutex_lock() {
                # containing directory is changed. Hence, we can
                # watch the containing directory instead.
 
-               if ! inotifywait -qq "${lock%/*}"; then
+               if ! inotifywait -qq "${lock%/*}" -t "$timeout"; then
                        return 1
                fi
        done
index 868d61be12b528d769f23c09b9c4962104e2302a..8308ab4e0996c7bb71b2507b47f644b90081e911 100644 (file)
@@ -363,6 +363,7 @@ queue_put_file() {
 
 queue_get() {
        local queue="$1"
+       local -i timeout="$2"
 
        local sem
        local mutex
@@ -376,7 +377,7 @@ queue_get() {
 
        err=false
 
-       if ! sem_wait "$sem"; then
+       if ! sem_wait "$sem" "$timeout"; then
                return 1
        fi
 
@@ -403,6 +404,7 @@ queue_get() {
 queue_get_file() {
        local queue="$1"
        local destdir="$2"
+       local -i timeout="$3"
 
        local sem
        local mutex
@@ -424,7 +426,7 @@ queue_get_file() {
 
        err=false
 
-       if ! sem_wait "$sem"; then
+       if ! sem_wait "$sem" "$timeout"; then
                return 1
        fi
 
index 2a1e3975a6531918b65d920cb9b6c19809613562..6c6ef6e03f8a46667dcb493be3df5e45ab50761c 100644 (file)
@@ -173,6 +173,7 @@ sem_destroy() {
 
 sem_wait() {
        local name="$1"
+       local -i timeout="$2"
 
        local waitlock
        local countlock
@@ -184,7 +185,7 @@ sem_wait() {
        counter=$(_sem_get_counter "$name")
        err=1
 
-       if ! wmutex_lock "$waitlock"; then
+       if ! wmutex_lock "$waitlock" "$timeout"; then
                return 1
        fi
 
index 3b78d617a6b4aec6b862229a1b1cb344160c2444..ff732bd9e7e91706eb6f06bcd7e9fb2b4dadeeb1 100644 (file)
@@ -21,9 +21,10 @@ wmutex_trylock() {
 
 wmutex_lock() {
        local lock="$1"
+       local -i timeout="$2"
 
        while ! wmutex_trylock "$lock"; do
-               if ! inotifywait -qq "${lock%/*}"; then
+               if ! inotifywait -qq "${lock%/*}" -t "$timeout"; then
                        return 1
                fi
        done