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.
mutex_lock() {
local lock="$1"
+ local -i timeout="$2"
while ! mutex_trylock "$lock"; do
# We can't inotifywait on symlinks. Which is
# 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
queue_get() {
local queue="$1"
+ local -i timeout="$2"
local sem
local mutex
err=false
- if ! sem_wait "$sem"; then
+ if ! sem_wait "$sem" "$timeout"; then
return 1
fi
queue_get_file() {
local queue="$1"
local destdir="$2"
+ local -i timeout="$3"
local sem
local mutex
err=false
- if ! sem_wait "$sem"; then
+ if ! sem_wait "$sem" "$timeout"; then
return 1
fi
sem_wait() {
local name="$1"
+ local -i timeout="$2"
local waitlock
local countlock
counter=$(_sem_get_counter "$name")
err=1
- if ! wmutex_lock "$waitlock"; then
+ if ! wmutex_lock "$waitlock" "$timeout"; then
return 1
fi
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