Bug 423131 - powerdevil does not release pending Inhibit cookie if source application exits too quickly
Summary: powerdevil does not release pending Inhibit cookie if source application exit...
Status: RESOLVED FIXED
Alias: None
Product: Powerdevil
Classification: Plasma
Component: general (show other bugs)
Version: 5.19.1
Platform: Gentoo Packages Linux
: NOR normal
Target Milestone: ---
Assignee: Plasma Bugs List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-06-18 04:59 UTC by Gabriel Marcano
Modified: 2020-06-22 09:51 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In: 5.18.6


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Gabriel Marcano 2020-06-18 04:59:06 UTC
SUMMARY

Powerdevil delays registering an Inhibit request from dbus for 5 seconds (commit eca79138c). If the requesting application/service dies during those 5 seconds, the Inhibit is still registered.


STEPS TO REPRODUCE
1. Launch an application that sends a request to Inhibit via org.freedesktop.PowerManagement.Inhibit.Inhibit or directly to Powerdevil via its dbus interface. I used the elisa music player.
2. Have said application send an Inhibit. With elisa, just play some music.
3. Exit the application before 5 seconds after sending an Inhibit. With elisa, that's just exiting the application quickly after pressing play.

OBSERVED RESULT
Using:
watch -n1 dbus-send --session --dest=org.kde.Solid.PowerManagement.PolicyAgent --type=method_call --print-reply /org/kde/Solid/PowerManagement/PolicyAgent org.kde.Solid.PowerManagement.PolicyAgent.ListInhibitions

A new inhibition is listed after the application has exited, 5 seconds after the inhibit was sent.

EXPECTED RESULT
No new inhibition is listed by the application that just exited.


SOFTWARE/OS VERSIONS
Linux/KDE Plasma: Gentoo Linux (unstable)
(available in About System)
KDE Plasma Version: 5.19.1
KDE Frameworks Version: 5.71.0
Qt Version: 5.15.0

ADDITIONAL INFORMATION
I found this while debugging bug #421662 . While arguably elisa should be sending an inhibit on a controlled exit (it can't reasonably do this if it gets a SIGTERM or SIGKILL, or triggers a SIGSEGV, though), there is code in Powerdevil to handle cases where the external service exits without getting rid of the inhibitor. In fact, if I exit elisa after the Inhibit has posted successfully, I do see the Inhibit being removed by Powerdevil.

The root of the problem is that currently, due to commit eca79138c, Powerdevil quasi-registers the pending request, but it doesn't actually fully register it so that the service is being listened to in case it dies. Specifically, in daemon/powerdevilpolicyagent.cpp:

    m_busWatcher.data()->addWatchedService(service);

isn't called until after the 5 second timer goes off.

From what I can tell, this file hasn't changed since 5.19.1 and the current master commit b009a7d856220b9ca64e34cc887069798c801fe9.

I'm experimenting to see what could be a possible solution, but I'm not familiar with the codebase. In addition, due to contract clauses with my employer, I can't provide patches without their permission, at least until I am no longer employed by them. I may be able to provide ideas, though, once I come up with something that works.
Comment 1 Gabriel Marcano 2020-06-18 06:19:09 UTC
I think the solution is to move the m_busWatcher parts in addInhibitionWithExplicitDBusService and ReleaseInhibition further up, so that they are processed before the functions are short-circuited by the pending checks. This way a service will be registered as soon as we have even a pending request, and thus the pending cookie will be released properly when that service dies or goes away.
Comment 2 Bug Janitor Service 2020-06-19 17:54:04 UTC
A possibly relevant merge request was started @ https://invent.kde.org/plasma/powerdevil/-/merge_requests/8
Comment 3 Kai Uwe Broulik 2020-06-22 09:51:06 UTC
Git commit d21102cc6c7a4db204a29f376ce5eb316ef57a6e by Kai Uwe Broulik.
Committed on 19/06/2020 at 17:51.
Pushed by broulik into branch 'Plasma/5.18'.

Watch DBus service right away to discard pending inhibitions reliably

PowerDevil delays applying a power management inhibition by 5 seconds to avoid brief inhibitions
to e.g. wake up the screen and similar.
However, when an inhibition was posted and the process then quit, we would then still
enforce the inhibition as it wasn't explicitly revoked.
Fix this by always watching the inhibition sender and remove it from pending when the
service goes away.
FIXED-IN: 5.18.6

M  +12   -14   daemon/powerdevilpolicyagent.cpp

https://invent.kde.org/plasma/powerdevil/commit/d21102cc6c7a4db204a29f376ce5eb316ef57a6e