diff options
author | Mihai Moldovan <ionic@ionic.de> | 2023-02-22 09:06:26 +0100 |
---|---|---|
committer | Mihai Moldovan <ionic@ionic.de> | 2023-02-22 09:06:31 +0100 |
commit | 30035fe8aa2d388b2493cafc4f5b17755b99a0f1 (patch) | |
tree | e70a2545e07aacca8bf6303a1af417512f6303eb | |
parent | a008c6c1e4f079332e69c02914612ce586a95ae0 (diff) | |
download | arctica-greeter-30035fe8aa2d388b2493cafc4f5b17755b99a0f1.tar.gz arctica-greeter-30035fe8aa2d388b2493cafc4f5b17755b99a0f1.tar.bz2 arctica-greeter-30035fe8aa2d388b2493cafc4f5b17755b99a0f1.zip |
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
-rw-r--r-- | src/arctica-greeter.vala | 42 |
1 files 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 (); } /* |