From 30035fe8aa2d388b2493cafc4f5b17755b99a0f1 Mon Sep 17 00:00:00 2001 From: Mihai Moldovan Date: Wed, 22 Feb 2023 09:06:26 +0100 Subject: src/arctica-greeter.vala: fix test mode. 32d28d7bf2646fc7a0008937034246fcc96dbc8a broke test mode by changing the ArcticaGreeter class to a proper SingleInstance vala class. While meant well, this created deadlocks, especially when using test mode, since other code being called from the ArcticaGreeter constructor tries to acquire references to ArcticaGreeter, which is still locked at that point in time. Fortunately, GObject has the constructed () function, that is almost never used within vala, but still works and is called after the constructor () (or, in vala parlance, construct), so we can move calling functions that might require a constructed ArcticaGreeter to constructed (). Fixes: https://github.com/ArcticaProject/arctica-greeter/issues/42 --- src/arctica-greeter.vala | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/arctica-greeter.vala b/src/arctica-greeter.vala index 2ca188d..322f7e3 100644 --- a/src/arctica-greeter.vala +++ b/src/arctica-greeter.vala @@ -33,6 +33,7 @@ public class ArcticaGreeter : Object private string state_file; private KeyFile state; + private bool continue_init = false; private Cairo.XlibSurface background_surface; @@ -104,9 +105,10 @@ public class ArcticaGreeter : Object warning ("Failed to load state from %s: %s\n", state_file, e.message); } + /* Render things after xsettings is ready */ + xsettings_ready.connect ( xsettings_ready_cb ); + if (!test_mode) { - /* Render things after xsettings is ready */ - xsettings_ready.connect ( xsettings_ready_cb ); GLib.Bus.watch_name (BusType.SESSION, "org.mate.SettingsDaemon", BusNameWatcherFlags.NONE, (c, name, owner) => @@ -119,7 +121,7 @@ public class ArcticaGreeter : Object { if (name == "xsettings") { debug ("xsettings is ready"); - xsettings_ready (); + continue_init = true; } } ); @@ -127,13 +129,43 @@ public class ArcticaGreeter : Object catch (Error e) { debug ("Failed to get MSD proxy, proceed anyway"); - xsettings_ready (); + continue_init = true; } }, null); } else - xsettings_ready_cb (); + { + /* + * Since this is now a proper SingleInstance class, we have to + * make sure to finish constructing as early as possible. + * + * Calling xsettings_ready_cb () here is *not* possible, since the + * function calls a lot of other things that eventually need a + * reference to ArcticaGreeter, but since we're still constructing + * it, fetching a reference would just deadlock. + * + * Fixing this isn't really easy. We cannot use timeouts, since we + * don't have a main loop available at that point in time. + * + * Fortunately, GObject's initialization sequence is quite + * sophisticated and provides a way to run code after the + * constructor function (i.e., this one) has finished - the + * virtual constructed function. + */ + continue_init = true; + } + } + + public override void constructed () + { + if (continue_init) + { + xsettings_ready (); + } + + /* Chain up - actually necessary. */ + base.constructed (); } /* -- cgit v1.2.3