Rely on /sys/power/wake_lock

Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
Signed-off-by: Peter John Hartman <peterjohnhartman@gmail.com>
This commit is contained in:
Willow Barraco
2023-02-23 13:20:05 +01:00
committed by Peter John Hartman
parent b204be1d86
commit 89a77e6057
28 changed files with 272 additions and 370 deletions

View File

@@ -11,7 +11,8 @@ OPENRC:=1
CC ?= $(CROSS_COMPILE)gcc
PROGRAMS = \
programs/sxmo_aligned_sleep \
programs/sxmo_vibrate
programs/sxmo_vibrate \
programs/sxmo_wakeafter
all: $(PROGRAMS)
@@ -23,6 +24,9 @@ shellcheck:
programs/%: programs/%.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $<
programs/sxmo_wakeafter: programs/sxmo_wakeafter.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -Wl,--no-as-needed -lcap -o $@ $<
clean:
rm -f programs/sxmo_aligned_sleep programs/sxmo_vibrate
@@ -73,6 +77,8 @@ install-scripts: $(PROGRAMS)
install -D programs/sxmo_aligned_sleep $(DESTDIR)$(PREFIX)/bin/
install -D programs/sxmo_vibrate $(DESTDIR)$(PREFIX)/bin/
install -D programs/sxmo_wakeafter $(DESTDIR)$(PREFIX)/bin/
setcap 'cap_block_suspend=p cap_wake_alarm=p' $(DESTDIR)$(PREFIX)/bin/sxmo_wakeafter
find $(DESTDIR)$(PREFIX)/share/sxmo/default_hooks/ -type f -exec ./setup_config_version.sh "{}" \;
find $(DESTDIR)$(PREFIX)/share/sxmo/appcfg/ -type f -exec ./setup_config_version.sh "{}" \;

View File

@@ -2,6 +2,10 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
if [ -f /sys/power/wake_lock ]; then
echo not_screenoff | doas tee -a /sys/power/wake_lock > /dev/null
fi
# Go to locker after 5 minutes of inactivity
if [ -e "$XDG_CACHE_HOME/sxmo/sxmo.noidle" ]; then
sxmo_daemons.sh stop idle_locker

View File

@@ -6,14 +6,8 @@
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
# UNSUSPENDREASON="$1"
#The UNSUSPENDREASON can be "usb power", "cover", "rtc" (real-time clock
#periodic wakeup) or "button". You will likely want to check against this and
#decide what to do
light -S "$(cat "$XDG_RUNTIME_DIR"/sxmo.brightness.presuspend.state)"
sxmo_hook_unlock.sh
if [ -f /sys/power/wake_lock ]; then
echo "stay_awake ${SXMO_UNLOCK_IDLE_TIME:-120}000000000" | doas tee -a /sys/power/wake_lock > /dev/null
fi
# Add here whatever you want to do

View File

@@ -1,29 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# This script is called prior to suspending
# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
pkill clickclack
sxmo_keyboard.sh close
pkill mpv #if any audio/video is playing, kill it (it might stutter otherwise)
case "$SXMO_WM" in
dwm)
sxmo_dmenu.sh close
;;
esac
printf "SUSPEND" > "$SXMO_STATE"
sxmo_hook_statusbar.sh state_change
# store brightness state and set it to zero
light > "$XDG_RUNTIME_DIR"/sxmo.brightness.presuspend.state
light -S 0
sleep 1s # give statusbar a second to update
# Add here whatever you want to do

View File

@@ -11,6 +11,10 @@
sxmo_log "transitioning to stage unlock"
printf unlock > "$SXMO_STATE"
if [ -f /sys/power/wake_lock ]; then
echo "stay_awake ${SXMO_UNLOCK_IDLE_TIME:-120}000000000" | doas tee -a /sys/power/wake_lock > /dev/null
fi
sxmo_hook_statusbar.sh state_change &
sxmo_wm.sh dpms off
@@ -18,14 +22,11 @@ sxmo_wm.sh inputevent touchscreen on
sxmo_wm.sh inputevent stylus on
superctl start sxmo_hook_lisgd
# suspend after 30s
# the periodic mutex check is necessary to 'free' old mutex, I think.
if ! [ -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend" ]; then
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
timeout "${SXMO_UNLOCK_IDLE_TIME:-120}" 'sxmo_daemons.sh start crustin sxmo_run_periodically.sh 5 sh -c "sxmo_hook_check_state_mutexes.sh && exec sxmo_mutex.sh can_suspend holdexec sxmo_suspend.sh"' \
resume 'sxmo_daemons.sh stop crustin' \
timeout "$((${SXMO_UNLOCK_IDLE_TIME:-120}+10))" 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh' \
resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
fi
sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh
# suspend after if no activity after 120s
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
timeout "1" '' \
resume "echo \"stay_awake ${SXMO_UNLOCK_IDLE_TIME:-120}000000000\" | doas tee -a /sys/power/wake_lock > /dev/null"
wait

View File

@@ -5,46 +5,43 @@
# This hook goal is to setup mutexes if the device must be considered
# as idle or not, if it can go to crust or not
# WARNING: if you remove an entry, be sure to run `sxmo_mutex.sh can_suspend
# free "entry name"` afterwards.
# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
lock_suspend_mutex() {
if ! sxmo_mutex.sh can_suspend lockedby "$1"; then
sxmo_mutex.sh can_suspend lock "$1"
fi
echo "$1" | doas tee -a /sys/power/wake_lock > /dev/null
sxmo_debug "lock \"$1\""
}
free_suspend_mutex() {
sxmo_mutex.sh can_suspend free "$1"
echo "$1" | doas tee -a /sys/power/wake_unlock > /dev/null 2>&1
sxmo_debug "free \"$1\""
}
cleanup_main_mutex() {
free_suspend_mutex "Checking some mutexes"
free_suspend_mutex "checking_mutexes"
exit 0
}
exec 3<> "${XDG_RUNTIME_DIR:-$HOME}/sxmo.checkstatemutexes.lock"
flock -x 3
lock_suspend_mutex "Checking some mutexes"
lock_suspend_mutex "checking_mutexes"
trap 'cleanup_main_mutex' TERM INT EXIT
# ongoing_call
if pgrep -f sxmo_modemcall.sh > /dev/null; then
lock_suspend_mutex "Ongoing call"
lock_suspend_mutex "ongoing_call"
else
free_suspend_mutex "Ongoing call"
free_suspend_mutex "ongoing_call"
fi
# hotspot active
if nmcli -t c show --active | grep ^Hotspot; then
lock_suspend_mutex "Hotspot is active"
lock_suspend_mutex "hotspot_active"
else
free_suspend_mutex "Hotspot is active"
free_suspend_mutex "hotspot_active"
fi
ssh_connected() {
@@ -57,44 +54,44 @@ ssh_connected() {
# active_ssh
if ssh_connected; then
lock_suspend_mutex "SSH is connected"
lock_suspend_mutex "ssh_connected"
else
free_suspend_mutex "SSH is connected"
free_suspend_mutex "ssh_connected"
fi
# active_mosh
if command -v mosh-server > /dev/null && pgrep -f mosh-server > /dev/null; then
lock_suspend_mutex "Mosh is listening"
lock_suspend_mutex "mosh_listening"
else
free_suspend_mutex "Mosh is listening"
free_suspend_mutex "mosh_listening"
fi
# playing_mpc
if command -v mpc > /dev/null && mpc status 2>/dev/null | grep -q '\[playing\]'; then
lock_suspend_mutex "MPD is playing music"
lock_suspend_mutex "mpd_playing"
else
free_suspend_mutex "MPD is playing music"
free_suspend_mutex "mpd_playing"
fi
# mpris compatible media player
if command -v playerctl > /dev/null; then
if test "$(playerctl status 2>/dev/null)" = "Playing"; then
lock_suspend_mutex "MPRIS client is playing"
lock_suspend_mutex "mpris_playing"
else
free_suspend_mutex "MPRIS client is playing"
free_suspend_mutex "mpris_playing"
fi
fi
# photos_processing
if pgrep -f postprocess > /dev/null; then
lock_suspend_mutex "Camera postprocessing"
lock_suspend_mutex "camera_postprocessing"
else
free_suspend_mutex "Camera postprocessing"
free_suspend_mutex "camera_postprocessing"
fi
# auto_suspend
if [ -e "$XDG_CACHE_HOME/sxmo/sxmo.nosuspend" ]; then
lock_suspend_mutex "Manually disabled"
lock_suspend_mutex "manually_disabled"
else
free_suspend_mutex "Manually disabled"
free_suspend_mutex "manually_disabled"
fi

View File

@@ -85,7 +85,7 @@ case "$WMCLASS" in
$icon_clk Change Timezone ^ 1 ^ sxmo_timezonechange.sh
$icon_zzz Auto-suspend $(
[ -e "$XDG_CACHE_HOME"/sxmo/sxmo.nosuspend ] && printf "%s" "$icon_tof" || printf "%s" "$icon_ton"
) ^ 1 ^ (rm $XDG_CACHE_HOME/sxmo/sxmo.nosuspend || touch $XDG_CACHE_HOME/sxmo/sxmo.nosuspend); sxmo_hook_check_state_mutexes.sh
) ^ 1 ^ (rm $XDG_CACHE_HOME/sxmo/sxmo.nosuspend || touch $XDG_CACHE_HOME/sxmo/sxmo.nosuspend)
$icon_zzz Auto-screen-off $(
[ -e "$XDG_CACHE_HOME/sxmo/sxmo.noidle" ] && printf "%s" "$icon_tof" || printf "%s" "$icon_ton"
) ^ 1 ^ (rm $XDG_CACHE_HOME/sxmo/sxmo.noidle || touch $XDG_CACHE_HOME/sxmo/sxmo.noidle) && sxmo_hook_unlock.sh
@@ -109,7 +109,6 @@ case "$WMCLASS" in
CHOICES="
$icon_lck Lock ^ 0 ^ sxmo_hook_lock.sh
$icon_lck Lock (Screen off) ^ 0 ^ sxmo_hook_screenoff.sh
$icon_zzz Suspend ^ 0 ^ sxmo_hook_screenoff.sh && sxmo_suspend.sh
$icon_out Logout ^ 0 ^ confirm Logout && sxmo_power.sh logout
$([ -f "$(xdg_data_path xsessions/sxmo.desktop)" ] &&
[ -f "$(xdg_data_path wayland-sessions/swmo.desktop)" ] &&

View File

@@ -5,23 +5,10 @@
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
YEARS8_TO_SEC=268435455
if ! command -v mnc > /dev/null; then
exit 0
fi
time="$(crontab -l | grep sxmo_rtcwake | mnc)"
crontab -l | grep sxmo_rtcwake | mnc
# don't return time if it's too far in the future
if [ "$time" -ge "$YEARS8_TO_SEC" ]; then
exit 0
fi
# Exit status 1 indicates that there is a cron job soon
if [ "$time" -lt 10 ]; then
sxmo_log "next cron time ($time) is too soon"
exit 1
fi
echo "$((time - 10))"

View File

@@ -63,6 +63,11 @@ esac
# To setup initial lock state
sxmo_hook_unlock.sh
# Turn on auto-suspend
if [ -w "/sys/power/autosleep" ] && [ -f "/sys/power/wake_lock" ]; then
superctl start sxmo_autosuspend
fi
# Turn on lisgd
superctl start sxmo_hook_lisgd

View File

@@ -12,6 +12,10 @@ flock -x 3
sxmo_log "transitioning to stage lock"
printf lock > "$SXMO_STATE"
if [ -f /sys/power/wake_lock ]; then
echo not_screenoff | doas tee -a /sys/power/wake_lock > /dev/null
fi
# This hook is called when the system reaches a locked state
sxmo_led.sh blink blue &

View File

@@ -14,9 +14,9 @@ UNSUSPENDREASON="$1"
# stay awake if modem has crashed for 30s to give modem time to recover
modemloop() {
sxmo_mutex.sh can_suspend lock "! Modem crashed."
echo "modem_crashed" | doas tee -a /sys/power/wake_lock > /dev/null
sleep 30s
sxmo_mutex.sh can_suspend free "! Modem crashed."
echo "modem_crashed" | doas tee -a /sys/power/wake_unlock > /dev/null
}
if [ "$UNSUSPENDREASON" = "modem" ]; then

View File

@@ -1,25 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# This script is called prior to suspending
# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
sxmo_daemons.sh stop periodic_blink
pkill clickclack
sxmo_keyboard.sh close
pkill -INT mpv #if any audio/video is playing, kill it (it might stutter otherwise)
case "$SXMO_WM" in
sway)
makoctl dismiss -a # close all popups
;;
dwm)
sxmo_dmenu.sh close
dunstctl close all # close all popups
;;
esac

View File

@@ -31,15 +31,19 @@ case "$SXMO_WM" in
;;
esac
sxmo_hook_check_state_mutexes.sh
# Start a periodic daemon (8s) "try to go to crust" after 8 seconds
# Start a periodic daemon (2s) blink after 5 seconds
# Resume tasks stop daemons
sxmo_daemons.sh start idle_locker sxmo_idle.sh -w \
timeout 8 'sxmo_daemons.sh start going_deeper sxmo_run_periodically.sh 30 sh -c "sxmo_hook_check_state_mutexes.sh && exec sxmo_mutex.sh can_suspend holdexec sxmo_suspend.sh"' \
resume 'sxmo_daemons.sh stop going_deeper' \
timeout 5 'sxmo_daemons.sh start periodic_blink sxmo_run_periodically.sh 2 sxmo_led.sh blink red blue' \
timeout 2 'sxmo_daemons.sh start periodic_blink sxmo_run_periodically.sh 2 sxmo_led.sh blink red blue' \
resume 'sxmo_daemons.sh stop periodic_blink' \
timeout 12 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh' \
timeout 10 'sxmo_daemons.sh start periodic_state_mutex_check sxmo_run_periodically.sh 10 sxmo_hook_check_state_mutexes.sh' \
resume 'sxmo_daemons.sh stop periodic_state_mutex_check'
wait
if [ -f /sys/power/wake_unlock ]; then
echo not_screenoff | doas tee -a /sys/power/wake_unlock > /dev/null
fi

View File

@@ -14,6 +14,10 @@ flock -x 3
sxmo_log "transitioning to stage unlock"
printf unlock > "$SXMO_STATE"
if [ -f /sys/power/wake_lock ]; then
echo not_screenoff | doas tee -a /sys/power/wake_lock > /dev/null
fi
sxmo_led.sh blink red green &
sxmo_hook_statusbar.sh state_change &
@@ -51,7 +55,4 @@ else
esac
fi
sxmo_daemons.sh start periodic_state_mutex_check \
sxmo_run_aligned.sh 60 sxmo_hook_check_state_mutexes.sh
wait

View File

@@ -16,3 +16,5 @@ permit nopass :wheel as root cmd systemctl args start eg25-manager
permit nopass :wheel as root cmd systemctl args stop eg25-manager
permit nopass :wheel as root cmd systemctl args start ModemManager
permit nopass :wheel as root cmd systemctl args stop ModemManager
permit nopass :wheel as root cmd tee args -a /sys/power/wake_lock
permit nopass :wheel as root cmd tee args -a /sys/power/wake_unlock

View File

@@ -0,0 +1,7 @@
[Unit]
Description=daemon for autosuspending
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/sxmo_autosuspend.sh

130
programs/sxmo_wakeafter.c Normal file
View File

@@ -0,0 +1,130 @@
#include <errno.h> // error handling
#include <stdint.h> // uint64_t type
#include <stdio.h> // dprintf
#include <stdlib.h> // strtol, exit
#include <string.h> // strerror
#include <sys/timerfd.h> // timers
#include <unistd.h> // read
#include <sys/epoll.h> // epoll_*
#include <sys/capability.h> // cap_*
#define MAX_EVENTS 1
#define try(func, args...) { \
if (-1 == func(args)) { \
perror(#func); \
return 1; \
} \
}
#define eprintf(...) fprintf (stderr, __VA_ARGS__)
void error(char *message, int err) {
dprintf(2, "%s: %s\n", message, strerror(err));
exit(1);
}
void usage(char *name) {
eprintf(
"%s: <seconds> <command>\n"
"\tRun <command> after <seconds> or after a suspension wake up. "
"Hold the system awake until the command finished\n",
name
);
}
void check_cap_avail(cap_value_t cap) {
if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) {
fprintf(stderr, "ERROR: %s isn't available on your system\n", cap_to_name(cap));
exit(1);
}
}
int check_perimsions() {
const cap_value_t cap_list[2] = {CAP_BLOCK_SUSPEND, CAP_WAKE_ALARM};
check_cap_avail(CAP_BLOCK_SUSPEND);
check_cap_avail(CAP_WAKE_ALARM);
cap_t caps = cap_get_proc();
if (caps == NULL) {
perror("cap_get_proc");
return 1;
}
try(cap_set_flag, caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET);
if (-1 == cap_set_proc(caps)) {
perror("cap_set_proc");
return 1;
}
try(cap_free, caps);
return 0;
}
int main(int argc, char **argv) {
uint64_t buf;
long duration = -1;
int time_fd, epollfd;
struct epoll_event ev, events[MAX_EVENTS];
struct timespec now;
struct itimerspec time = {
.it_value = { .tv_sec = 0, .tv_nsec = 0 },
.it_interval = { .tv_sec = 0, .tv_nsec = 0 }
};
// Check permissions
if (check_perimsions()) {
fprintf(stderr, "Hint: make sure this executeable has the "
"cap_block_suspend and cap_wake_alarm privilages\n");
return 1;
}
// Process arguments
if (argc != 3) {
usage(argv[0]);
return 1;
}
duration = strtol(argv[1], NULL, 0);
if (duration <= 0 || errno == ERANGE) {
usage(argv[0]);
eprintf("Error: seconds must be a positive integer\n");
return 1;
}
// Create timer
if ((time_fd = timerfd_create(CLOCK_REALTIME_ALARM, 0)) == -1)
error("Failed to create timerfd", errno);
// Setup epoll
epollfd = epoll_create1(0);
ev.events = EPOLLIN | EPOLLWAKEUP;
ev.data.fd = time_fd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, time_fd, &ev);
// Calculate absolute time to wakeup
try(clock_gettime, CLOCK_REALTIME, &now);
time.it_value.tv_sec = now.tv_sec + duration;
time.it_value.tv_nsec = now.tv_nsec;
/* if (timerfd_settime(time_fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, &time, NULL) == -1) { */
try(timerfd_settime, time_fd, TFD_TIMER_ABSTIME, &time, NULL);
// Wait for timer
int ret;
do {
ret = epoll_wait(epollfd, events, MAX_EVENTS, -1);
if (ret == -1 && errno == EINTR) {
eprintf("Woke up\n");
break;
}
} while (ret < 1);
system(argv[2]);
}

View File

@@ -50,39 +50,53 @@ whichWake() {
echo "button"
}
sxmo_log "going to suspend to crust"
saveAllEventCounts
sxmo_hook_presuspend.sh
sxmo_led.sh blink red
if suspend_time="$(sxmo_hook_mnc.sh)"; then
sxmo_log "calling suspend with suspend_time <$suspend_time>"
start="$(date "+%s")"
sxmo_hook_suspend.sh "$suspend_time"
#We woke up again
time_spent="$(( $(date "+%s") - start ))"
if [ "$suspend_time" -gt 0 ] && [ "$((time_spent + 10))" -ge "$suspend_time" ]; then
UNSUSPENDREASON="rtc"
else
UNSUSPENDREASON="$(whichWake)"
finish() {
if [ -n "$INITIAL" ]; then
echo "$INITIAL" > /sys/power/autosleep
fi
else
sxmo_log "fake suspend (suspend_time ($suspend_time) less than zero)"
UNSUSPENDREASON=rtc # we fake the crust for those seconds
kill "$WAKEPID"
exit
}
autosuspend() {
YEARS8_TO_SEC=268435455
INITIAL="$(cat /sys/power/autosleep)"
trap 'finish' TERM INT EXIT
while : ; do
# necessary?
echo "$INITIAL" > /sys/power/autosleep
suspend_time=99999999 # far away
mnc="$(sxmo_hook_mnc.sh)"
if [ -n "$mnc" ] && [ "$mnc" -gt 0 ] && [ "$mnc" -lt "$YEARS8_TO_SEC" ]; then
if [ "$mnc" -le 15 ]; then # cronjob imminent
echo "waiting_cronjob" | doas tee -a /sys/power/wake_lock > /dev/null
suspend_time=$((mnc + 1)) # to arm the following one
else
suspend_time=$((mnc - 10))
fi
fi
sxmo_wakeafter "$suspend_time" "sxmo_autosuspend.sh wokeup" &
WAKEPID=$!
sleep 1 # wait for it to epoll pwait
echo mem > /sys/power/autosleep
wait
done
}
wokeup() {
# 10s basic hold
echo "woke_up 10000000000" | doas tee -a /sys/power/wake_lock > /dev/null
sxmo_hook_postwake.sh
}
if [ -z "$*" ]; then
set -- autosuspend
fi
echo "$UNSUSPENDREASON" > "$SXMO_UNSUSPENDREASONFILE"
sxmo_log "woke up from crust (reason=$UNSUSPENDREASON)"
if [ "$UNSUSPENDREASON" = "rtc" ]; then
sxmo_mutex.sh can_suspend lock "Waiting for cronjob"
fi
sxmo_hook_postwake.sh "$UNSUSPENDREASON"
"$@"

View File

@@ -6,12 +6,12 @@
. sxmo_common.sh
free_mutex() {
sxmo_mutex.sh can_suspend free "Playing with leds"
echo "playing_with_leds" | doas tee -a /sys/power/wake_unlock > /dev/null
exit
}
ensure_mutex() {
sxmo_mutex.sh can_suspend lock "Playing with leds"
echo "playing_with_leds" | doas tee -a /sys/power/wake_lock > /dev/null
trap 'free_mutex' TERM INT
}

View File

@@ -1,92 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
set -e
MUTEX_NAME="$1"
shift
ROOT_DIR="${XDG_RUNTIME_DIR:-/dev/shm/user/$(id -u)}"/sxmo_mutex
REASON_FILE="$ROOT_DIR/$MUTEX_NAME"
mkdir -p "$(dirname "$REASON_FILE")"
exec 3>"$REASON_FILE.lock"
touch "$REASON_FILE"
lock() {
flock 3
REASON="$1"
printf "%s\n" "$REASON" >> "$REASON_FILE"
sxmo_debug "lock \"$MUTEX_NAME\", total: $(wc -l < "$REASON_FILE"), \"$REASON\""
}
free() {
flock 3
REASON="$1"
grep -xnm1 "$REASON" "$REASON_FILE" | \
cut -d: -f1 | \
xargs -r -I{} sed -i '{}d' "$REASON_FILE"
sxmo_debug "free \"$MUTEX_NAME\", total: $(wc -l < "$REASON_FILE"), \"$REASON\""
}
lockedby() {
sxmo_debug "Lockedby: $1"
grep -qxm1 "$1" "$REASON_FILE"
}
freeall() {
printf "" > "$REASON_FILE"
sxmo_hook_statusbar.sh lockedby
sxmo_log "freeall($MUTEX_NAME)"
}
list() {
cat "$REASON_FILE"
}
hold() {
if ! [ -s "$REASON_FILE" ]; then
exit 0
fi
FIFO="$(mktemp -u)"
mkfifo "$FIFO"
inotifywait -mq -e "close_write" "$ROOT_DIR" >> "$FIFO" &
NOTIFYPID=$!
# shellcheck disable=SC2317
finish() {
kill "$NOTIFYPID" 2>/dev/null
rm "$FIFO"
exit 0
}
trap 'finish' TERM INT EXIT
# shellcheck disable=SC2034
while read -r _; do
if ! [ -s "$REASON_FILE" ]; then
exit 0
fi
done < "$FIFO"
}
holdexec() {
# shellcheck disable=SC2317
finish() {
kill "$HOLDPID" 2>/dev/null
exit
}
trap 'finish' TERM INT
hold &
HOLDPID=$!
wait "$HOLDPID"
"$@"
}
"$@"

View File

@@ -2,10 +2,4 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
sxmo_mutex.sh can_suspend list
tail -f "$XDG_STATE_HOME"/sxmo.log | stdbuf -oL grep 'sxmo_mutex.sh'
watch 'cat /sys/power/wake_lock | tr " " "\n"'

View File

@@ -19,7 +19,7 @@ finish() {
# (see static const int stk3310_ps_max[4])
printf 6553 > "$prox_path/events/in_proximity_thresh_rising_value"
sxmo_mutex.sh can_suspend free "Proximity lock is running"
echo "proximity_lock_running" | doas tee -a /sys/power/wake_unlock > /dev/null
sxmo_daemons.sh start state_change_bar sxmo_hook_statusbar.sh state_change
exec sxmo_hook_"$INITIALSTATE".sh
@@ -50,8 +50,7 @@ trap 'finish' TERM INT
sxmo_daemons.sh stop idle_locker
sxmo_mutex.sh can_suspend lock "Proximity lock is running"
sxmo_hook_statusbar.sh lockedby
echo "proximity_lock_running" | doas tee -a /sys/power/wake_lock > /dev/null
sxmo_daemons.sh start state_change_bar sxmo_hook_statusbar.sh state_change
# find the device

View File

@@ -8,13 +8,11 @@
. sxmo_common.sh
# We can have multiple cronjobs at the same time
sxmo_mutex.sh can_suspend lock "Executing cronjob"
sxmo_mutex.sh can_suspend free "Waiting for cronjob"
sxmo_hook_statusbar.sh lockedby
echo "executing_cronjob" | doas tee -a /sys/power/wake_lock > /dev/null
echo "waiting_cronjob" | doas tee -a /sys/power/wake_unlock > /dev/null
finish() {
sxmo_mutex.sh can_suspend free "Executing cronjob"
sxmo_hook_statusbar.sh lockedby
echo "executing_cronjob" | doas tee -a /sys/power/wake_unlock > /dev/null
exit 0
}

View File

@@ -18,7 +18,7 @@ fi
# users can override this in sxmo_deviceprofile_mydevice.sh
files="${SXMO_SYS_FILES:-"/sys/power/state /sys/power/mem_sleep /dev/rtc0"}"
for file in $files; do
for file in $files /sys/power/autosleep; do
[ -e "$file" ] && chmod a+rw "$file"
done

View File

@@ -34,7 +34,7 @@ update_nixos() {
echo "Upgrade complete - reboot for all changes to take effect"
}
sxmo_mutex.sh can_suspend lock "Upgrading"
echo "upgrading" | doas tee -a /sys/power/wake_lock > /dev/null
case "$OS" in
alpine|postmarketos) update_apk;;
@@ -42,4 +42,4 @@ case "$OS" in
nixos) update_nixos;;
esac
sxmo_mutex.sh can_suspend free "Upgrading"
echo "upgrading" | doas tee -a /sys/power/wake_unlock > /dev/null

View File

@@ -286,8 +286,6 @@ processmms() {
fi
}
sxmo_mutex.sh can_suspend lock "Modem is used"
sxmo_hook_statusbar.sh lockedby
echo "mms_processing" | doas tee -a /sys/power/wake_lock > /dev/null
"$@"
sxmo_mutex.sh can_suspend free "Modem is used"
sxmo_hook_statusbar.sh lockedby
echo "mms_processing" | doas tee -a /sys/power/wake_unlock > /dev/null

View File

@@ -260,8 +260,6 @@ checkfornewtexts() {
done
}
sxmo_mutex.sh can_suspend lock "Modem is used"
sxmo_hook_statusbar.sh lockedby
echo "modem_used" | doas tee -a /sys/power/wake_lock > /dev/null
"$@"
sxmo_mutex.sh can_suspend free "Modem is used"
sxmo_hook_statusbar.sh lockedby
echo "modem_used" | doas tee -a /sys/power/wake_unlock > /dev/null

View File

@@ -1,94 +0,0 @@
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# shellcheck disable=SC2155
export PATH="$PATH:$(pwd)/scripts/core:$(pwd)/configs/default_hooks"
XDG_RUNTIME_DIR="$(mktemp -d)"
XDG_STATE_HOME="$(mktemp -d)"
export XDG_RUNTIME_DIR
export XDG_STATE_HOME
Describe 'sxmo_mutex.sh'
# Make sure we're running in a somewhat clean environment
setup() {
sh scripts/core/sxmo_mutex.sh shellspec_mutex freeall
}
BeforeAll 'setup'
# TODO: refactor script so it can be included instead of calling it
# Include scripts/core/sxmo_mutex.sh
It 'can list an empty lock'
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
The output should equal ''
The status should be success
End
It 'can acquire a lock'
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex lock shellspec
The status should be success
End
It 'can list an acquired lock'
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
The output should equal 'shellspec'
End
It 'can free a lock'
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex free shellspec
The status should be success
End
It 'does not list a freed lock'
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
The output should equal ''
End
IDS="$(seq 1 100)"
many_lock() {
set -e
for id in $IDS; do
sh scripts/core/sxmo_mutex.sh shellspec_mutex lock "$id" &
done
wait
}
It 'can handle concurrent locks'
When call many_lock
The status should be success
End
It 'lists all concurrently added locks'
list() {
sh scripts/core/sxmo_mutex.sh shellspec_mutex list | sort
}
When call list
# shellcheck disable=SC2086
The output should equal "$(printf "%s\n" $IDS | sort)"
End
many_unlock() {
set -e
for id in $IDS; do
[ "$id" = 50 ] && continue
sh scripts/core/sxmo_mutex.sh shellspec_mutex free "$id" &
done
wait
}
It 'can handle concurrent unlocks'
When call many_unlock
The status should be success
End
It 'clears all locks after they are unlocked'
When call sh scripts/core/sxmo_mutex.sh shellspec_mutex list
The output should equal "50"
End
End