avd/avds
Narvin Singh 4ddf06147d Fix: Failure to find daemon after PID changes
It looks like if the daemon is started in the .xinitrc, its PID
can change once the X session is fully started. This will cause
long-running schedulers that were started along with the daemon
to not find it and exit soon after the session is started. So have
the schedulers check for the newest daemon instance each time they
are about to send it a signal. This is probably more efficient than
before when we were getting the PID once when the scheduler starts,
because the scheduler would validate that the PID still referred to
a daemon each time it sent a signal. Getting the PID replaces that
validation check, and may actually be faster.
2020-12-31 18:41:29 -05:00

100 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
USAGE="
USAGE: avds <action> [<when>] [<repeat>]
action A comma or space separated list of actions to associate with the
update signal.
when The integer number of milliseconds to wait before sending the
update signal, or one of the following values:
- m to send the update signal at the top of the next minute
- h to send the update signal at the top of the next hour
- d to send the update signal at the top of the next day
If not present, the update signal will be sent immediately.
repeat If present, the update signal will be sent repeatedly according
to <when>.
EXAMPLES:
If the daemon interprets the actions 'vol' and 'bl' to mean update the
volume and backlight statuses, respectively, send a signal to
immediately update both of those statuses.
avds 'vol,bl'
If the daemon interprets the actions 'cpu' and 'mem' to mean update the
cpu and memory usage statuses, respectively, send a signal to update
both of those statuses every 5 seconds.
avds 'cpu,mem' 5000 1
If the daemon interprets the actions 'bat' and 'dt' to mean update the
battery and date/time statuses, respectively, send a signal to update
both of those statuses at the top of every minute.
avds 'bat,dt' m true
"
DAEMON=avdd
ACTION_DIR=/tmp/"${DAEMON}"
# Convert integer milliseconds to floating point seconds
ms_to_s () {
printf '%.3f' "${1}e-3"
}
# Validate the arguments
if [[ "$#" -lt 1 || "$#" -gt 3 ]]; then
printf '%s' "${USAGE}" 1>&2
exit 128
fi
IFS=', ' read -r -a actions <<< "$1"
when="${2:-0}"
repeat="$3"
if [[ ! "${when}" =~ ^[0-9]+|[mhd]$ ]]; then
printf 'Invalid argument <when>: %s\n' "${when}" 1>&2
exit 128
fi
# Send the signal if this is the first run or if repeat is on
first_run=1
while [[ "${first_run}" -eq 1 || -n "${repeat}" ]]; do
first_run=0
# Sleep until it's time to send the signal
if [[ "${when}" != '0' ]]; then
if [[ "${when}" =~ ^[0-9]+$ ]]; then
sleep "$(ms_to_s "${when}")"
else
case "${when}" in
m)
sleep $((60 - $(date +%S)))
;;
h)
readarray -t ms < <(date +'%M%n%S')
sleep $((3600 - ms[0] * 60 - ms[1]))
;;
d)
readarray -t hms < <(date +'%H%n%M%n%S')
sleep $(((24 - hms[0]) * 3600 - hms[1] * 60 - hms[2]))
;;
*)
;;
esac
fi
fi
# Create the signal data and send the signal to the daemon
daemon_pid="$(pgrep --newest --exact "${DAEMON}")"
if [[ -z "${daemon_pid}" ]]; then
printf 'The daemon %s is not running\n' "${DAEMON}" 1>&2
exit 1
fi
for action in "${actions[@]}"; do touch "${ACTION_DIR}/${action}"; done
kill -USR1 "${daemon_pid}"
done