Calling Inhibit+Uninhibit dbus methods of org.gnome.SessionManager multiple times slows down or freezes the system
Hi,
I am the author of a python library called wakepy. I'm trying to debug a strange bug which freezes the system if the going idle is inhibited and uninhibited repeatedly with org.gnome.SessionManager (See: wakepy/#277). If there are less repeats, the system will not freeze but becomes slow, and for example mouse cursor will experience lag/stutter until a reboot. I am using jeepney but the same issue can be reproduced with plain old dbus-python. Below are minimal working examples which will reproduce the freeze (you'll have to REISUB away from those):
MWE with jeepney
from jeepney import DBusAddress, new_method_call
from jeepney.io.blocking import open_dbus_connection
from jeepney.wrappers import unwrap_msg
addr = DBusAddress(
object_path="/org/gnome/SessionManager",
bus_name="org.gnome.SessionManager",
interface="org.gnome.SessionManager",
)
def call(method, signature=None, body=None):
msg = new_method_call(
addr,
method=method,
signature=signature,
body=body,
)
reply = connection.send_and_get_reply(msg, timeout=1)
return unwrap_msg(reply)
for i in range(10_000):
connection = open_dbus_connection(bus="SESSION")
cookie = call(
method="Inhibit",
signature="susu", # "app_id", "toplevel_xid", "reason", "flags"
body=("wakepy", 42, "wakelock active", 8),
)[0]
inhibitors = call(
method="GetInhibitors",
)[0]
print(f"{i}, {cookie=}, inhibitors = {len(inhibitors)}")
call(
method="Uninhibit",
signature="u", # "cookie"
body=(cookie,),
)
inhibitors = call(
method="GetInhibitors",
)[0]
print(f" {i}, {cookie=}, inhibitors = {len(inhibitors)}")
connection.close()
MWE with dbus-python
import dbus
for i in range(10_000):
session_bus = dbus.SessionBus()
proxy = session_bus.get_object(
"org.gnome.SessionManager", "/org/gnome/SessionManager"
)
cookie = proxy.get_dbus_method(
"Inhibit", dbus_interface="org.gnome.SessionManager"
)("wakepy", 42, "wakelock active", 8)
inhibitors = proxy.get_dbus_method(
"GetInhibitors", dbus_interface="org.gnome.SessionManager"
)()
print(f"{i}, {cookie=}, inhibitors = {len(inhibitors)}")
proxy.get_dbus_method("Uninhibit", dbus_interface="org.gnome.SessionManager")(
int(cookie)
)
inhibitors = proxy.get_dbus_method(
"GetInhibitors", dbus_interface="org.gnome.SessionManager"
)()
print(f" {i}, {cookie=}, inhibitors = {len(inhibitors)}")
session_bus.close()
Versions
- Ubuntu 22.04
- GNOME 42.9
- Python 3.10.12
- jeepney 0.8.0, dbus-python 1.3.2
Is this something expected? Are there any known workarounds, or has this been addressed already in newer GNOME versions?
Edited by Niko Föhr