
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.
100 lines
2.9 KiB
Bash
Executable File
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
|
|
|