From: Matthias Kruk Date: Sat, 29 May 2021 04:17:48 +0000 (+0900) Subject: include/{mutex,wmutex,sem,queue}: Add timeout argument to blocking functions X-Git-Url: https://git.corax.cc/?a=commitdiff_plain;h=df97069dce689b550183704d00cee8a9e51e4054;p=toolbox include/{mutex,wmutex,sem,queue}: Add timeout argument to blocking functions 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. --- diff --git a/include/mutex.sh b/include/mutex.sh index c05652f..4efd905 100644 --- a/include/mutex.sh +++ b/include/mutex.sh @@ -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 diff --git a/include/queue.sh b/include/queue.sh index 868d61b..8308ab4 100644 --- a/include/queue.sh +++ b/include/queue.sh @@ -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 diff --git a/include/sem.sh b/include/sem.sh index 2a1e397..6c6ef6e 100644 --- a/include/sem.sh +++ b/include/sem.sh @@ -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 diff --git a/include/wmutex.sh b/include/wmutex.sh index 3b78d61..ff732bd 100644 --- a/include/wmutex.sh +++ b/include/wmutex.sh @@ -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