From 1954a023524724ff3a9cf7887cef6aef2f6cb6af Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 8 Mar 2011 18:04:34 -0500 Subject: [PATCH] gnome-shell-jhbuild: Fix race condition when launching DConf manually We need to connect to the NameOwnerChanged signal before we execute the DConf binary. Refactor things so that we connect to the signal when we first get the bus object. Split the code for waiting for a D-Bus name into a wait_for_dbus_name() function for latter reuse. https://bugzilla.gnome.org/show_bug.cgi?id=644265 --- src/gnome-shell-jhbuild.in | 69 ++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/src/gnome-shell-jhbuild.in b/src/gnome-shell-jhbuild.in index f10a576ff..54dfed862 100755 --- a/src/gnome-shell-jhbuild.in +++ b/src/gnome-shell-jhbuild.in @@ -79,11 +79,56 @@ def get_running_session_environs(): result[key] = environs[key] return result +_bus = None +_bus_iface = None +_name_owner_changed_hook = None + +def on_name_owner_changed(name, prev_owner, new_owner): + if _name_owner_changed_hook: + _name_owner_changed_hook(name, prev_owner, new_owner) + +def get_bus(): + global _bus + if _bus is None: + dbus_loop = DBusGMainLoop() + _bus = dbus.SessionBus(mainloop=dbus_loop) + return _bus + +def get_bus_iface(): + global _bus_iface + if _bus_iface is None: + bus = get_bus() + bus_proxy = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') + _bus_iface = dbus.Interface(bus_proxy, 'org.freedesktop.DBus') + _bus_iface.connect_to_signal('NameOwnerChanged', on_name_owner_changed) + return _bus_iface + +def wait_for_dbus_name(wait_name): + global _name_owner_changed_hook + + bus_iface = get_bus_iface() + loop = gobject.MainLoop() + + def on_name_owner_changed(name, prev_owner, new_owner): + if not (name == wait_name and new_owner != ''): + return + loop.quit() + return + _name_owner_changed_hook = on_name_owner_changed + + def on_timeout(): + print "\nFailed to start %s: timed out" % (wait_name,) + sys.exit(1) + gobject.timeout_add_seconds(7, on_timeout) + + loop.run() + _name_owner_changed_hook = None + def start_dconf_await_service(): DCONF_NAME = 'ca.desrt.dconf' - dbus_loop = DBusGMainLoop() - bus = dbus.SessionBus(mainloop=dbus_loop) + bus = get_bus() + get_bus_iface() # connect to NameOwnerChanged signal # See if the service is already running or normal D-Bus activation works need_manual_activate = False @@ -122,25 +167,7 @@ def start_dconf_await_service(): print "\nFailed to start %s: %s" % (dconf_path, e) sys.exit(1) - bus_proxy = bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus') - bus_iface = dbus.Interface(bus_proxy, 'org.freedesktop.DBus') - - loop = gobject.MainLoop() - - def on_name_owner_changed(name, prev_owner, new_owner): - if not (name == DCONF_NAME and new_owner != ''): - return - print "started" - loop.quit() - return - bus_iface.connect_to_signal('NameOwnerChanged', on_name_owner_changed) - - def on_timeout(): - print "\nFailed to start %s: timed out" % (dconf_path,) - sys.exit(1) - gobject.timeout_add_seconds(7, on_timeout) - - loop.run() + wait_for_dbus_name (DCONF_NAME) def start_shell(perf_output=None): self_dir = os.path.dirname(os.path.abspath(sys.argv[0]))