Repository navigation
omamobile-sleepd: notice a resume when logind says so, not at the next poll - #642
Conversation
…t poll The watcher is frozen inside its sleep while the phone sleeps, so after a resume it only noticed it, and lit the PIN pad for a power-key wake, when the rest of that sleep ran out: 4.9 s after the kernel finished resuming on the Pixel 8 Pro with the toggle off (the 5 s poll), up to 2 s with it on. Listen for logind's PrepareForSleep(false) with busctl wait (a user service can't use busctl monitor) and end the wait with USR2 so the loop reads suspend_stats at once. PrepareForSleep(true) is ignored. The poll stays as the fallback: a raw write to /sys/power/state never sends the signal. The listener and busctl under it are killed with the watcher. Tests: a FIFO stands in for logind, a one-shot real hang for the frozen sleep; the new case fails on the old script.
|
@Somnius thank you, this is the right fix for a delay I had put down to the display. The explanation holds: the watcher is frozen inside its I checked the parts the PR rests on rather than taking them as read. What's left is mine to do: this changes when the PIN pad is lit after every resume on every phone, and so far it has run on your 8 Pro with the toggle off. Before I merge I'll run it on my Pixel 7 Pro: a power-key wake with the toggle off and five with it on, and a dark RTC wake to see the 5 s grace start at the resume. The thing I want to see there is Small things, none blocking:
I'll set the package version at merge (omamobile-shell 0.2.119, or 0.2.118 if this goes in before #640), so no need to touch |
|
The 7 Pro run is done, 2026-11-10: this branch merged with today's main, installed as omamobile-shell (a test build numbered 0.2.119), on Five sleeps, five wakes on the power key, each lit on the first press and staying lit:
Not run: the dark wake from an RTC alarm (the 5 s grace and the second sleep). My alarm didn't get set before the phone slept, so that case is still open; the phone did stay dark and asleep for several minutes and wake on the key. And the stop and start of the unit by hand (the listener going away with it) is covered by your test only. That was the one thing this was waiting for. The notes from my review are small and can come here or in a follow-up, as you prefer; I set the version at merge. |
… busctl busctl wait now names org.freedesktop.login1, so a PrepareForSleep from another process on the system bus is not taken for logind's. kill_tree takes a process's children's pids and kills the process first, so on a normal stop the listener can't get to its "no more resume events" line because busctl died under it. The test checks the sender in the arguments.
|
@Somnius thank you, both small points are in: the wait names Since the command changed after my Pixel 7 Pro run, I checked the new form with busctl 262 on my laptop: with the sender named it still waits without a timeout of its own (still waiting after 40 s), and the four-argument form delivers a signal. I'll look at the journal after the first sleep on the 7 Pro once this is installed and add the line here; I don't expect a difference. I'm setting the package version on your branch and merging (omamobile-shell 0.2.120, after #640). One request outside this PR: your traces here and in #640 are the first suspend results from a Pixel 8 Pro (a 58 s and a 10 minute s2idle through |
@derekross, next one from the suspend tests on the 8 Pro. After a power-key wake the lock screen took a few seconds to light, and the reason is in omamobile-sleepd: it only notices a resume by polling suspend_stats/success, and the watcher itself is frozen inside its
sleepwhile the phone sleeps. So after the kernel is back it finishes the rest of that sleep first. The poll is 2 s with the toggle on and the screen off behind a secure lock, 5 s otherwise.Measured with the monotonic journal on the phone (toggle off, so the 5 s branch), one power-key wake after a 58 s s2idle:
kernel "PM: suspend exit" at 85134.758
"omamobile-sleepd: resumed, woken by IRQ 100" at 85139.639
gs-decon back at 120 Hz at 85140.140
So the PIN pad was asked for 4.9 s after the kernel had resumed.
The change: the watcher also listens for logind's PrepareForSleep signal. When it says false (the sleep is over) the watcher gets a USR2 and its wait ends at once, so the loop reads suspend_stats and lights the screen right away. PrepareForSleep(true) is ignored. I used
busctl --system --json=short waitbecause a user service can't usebusctl monitor(it's refused for a normal user), and wait is in systemd 257 and later (the phone has 262). wait returns after every message, so the listener subscribes again each time. The poll stays as it was: a raw write to /sys/power/state never sends the signal, and if busctl fails or prints something unexpected the listener stops and says so in the log, then the watcher is on the old poll. The listener and the busctl under it are killed when the watcher stops.After, through
systemctl suspend(so logind sends the signal), final version of the script, about 10 minutes of s2idle, woken with the power key:kernel "PM: suspend exit" at 89427.464
"omamobile-sleepd: resumed, woken by IRQ 100" at 89427.522
"a power-key wake: lighting the lock screen" at 89427.530
gs-decon 120 Hz at 89428.010
That's 58 ms from the kernel to sleepd noticing, instead of 4.9 s (the first revision of this change gave 3.7 ms on the same test). The screen came on about half a second after the kernel resume, and that part is the display coming back, not sleepd.
Tests: test/sleepd.sh passes (7 groups, all ok). The new group uses a FIFO as the stand-in for logind, and a fake
sleepthat hangs for real without moving the clock, like the frozen sleep. It checks that a false ends the wait of the sleeping watcher (the run is limited to 10 s and the hang is 20 s), that a true before the false doesn't break the listener, that with no listener the poll still lights the PIN pad and the log says it gave up, and that nothing of the listener is left running after the watcher exits. I ran the same test against the old omamobile-sleepd and the "ends the wait" case fails (timed out).Not done / limits: there is still a tiny window right before
waitwhere a USR2 can be lost, which just costs one normal poll; same latency as before, not worse. I only tried it on my Pixel 8 Pro, with the sleep toggle off, so the 2 s branch wasn't measured, and a systemd older than 257 has no busctl wait (the listener then stops and logs it).