From: Alessandro Astone Date: Tue, 24 Jan 2023 22:12:53 +0000 (+0100) Subject: interfaces: Fix ServiceManager race condition in clients X-Git-Tag: 1.4.0~18 X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/waydroid.git/commitdiff_plain/21607bbefb2ec7cb04771ad6892a7b20f63f963e?ds=sidebyside interfaces: Fix ServiceManager race condition in clients --- diff --git a/tools/interfaces/IPlatform.py b/tools/interfaces/IPlatform.py index a5d6d08..12d1e1d 100644 --- a/tools/interfaces/IPlatform.py +++ b/tools/interfaces/IPlatform.py @@ -2,6 +2,8 @@ import gbinder import logging import time from tools import helpers +from gi.repository import GLib +import signal INTERFACE = "lineageos.waydroid.IPlatform" @@ -299,6 +301,13 @@ def get_service(args): serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL) except TypeError: serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER) + + if not serviceManager.is_present(): + logging.info("Waiting for binder Service Manager...") + if not wait_for_manager(serviceManager): + logging.error("Service Manager never appeared") + return None + tries = 1000 remote, status = serviceManager.get_service_sync(SERVICE_NAME) @@ -313,3 +322,14 @@ def get_service(args): return None return IPlatform(remote) + +# Like ServiceManager.wait() but can be interrupted +def wait_for_manager(sm): + mainloop = GLib.MainLoop() + sm.add_presence_handler(lambda: mainloop.quit() if sm.is_present() else None) + GLib.timeout_add_seconds(60, lambda: mainloop.quit()) + GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, lambda _: mainloop.quit(), None) + mainloop.run() + if not sm.is_present(): + return False + return True diff --git a/tools/interfaces/IStatusBarService.py b/tools/interfaces/IStatusBarService.py index fa5f6f5..af572dd 100644 --- a/tools/interfaces/IStatusBarService.py +++ b/tools/interfaces/IStatusBarService.py @@ -2,6 +2,8 @@ import gbinder import logging import time from tools import helpers +from gi.repository import GLib +import signal INTERFACE = "com.android.internal.statusbar.IStatusBarService" @@ -46,6 +48,13 @@ def get_service(args): serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER, args.SERVICE_MANAGER_PROTOCOL, args.BINDER_PROTOCOL) except TypeError: serviceManager = gbinder.ServiceManager("/dev/" + args.BINDER_DRIVER) + + if not serviceManager.is_present(): + logging.info("Waiting for binder Service Manager...") + if not wait_for_manager(serviceManager): + logging.error("Service Manager never appeared") + return None + tries = 1000 remote, status = serviceManager.get_service_sync(SERVICE_NAME) @@ -60,3 +69,14 @@ def get_service(args): return None return IStatusBarService(remote) + +# Like ServiceManager.wait() but can be interrupted +def wait_for_manager(sm): + mainloop = GLib.MainLoop() + sm.add_presence_handler(lambda: mainloop.quit() if sm.is_present() else None) + GLib.timeout_add_seconds(60, lambda: mainloop.quit()) + GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, lambda _: mainloop.quit(), None) + mainloop.run() + if not sm.is_present(): + return False + return True