aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Moldovan <ionic@ionic.de>2023-02-22 09:06:26 +0100
committerMihai Moldovan <ionic@ionic.de>2023-02-22 09:06:31 +0100
commit30035fe8aa2d388b2493cafc4f5b17755b99a0f1 (patch)
treee70a2545e07aacca8bf6303a1af417512f6303eb
parenta008c6c1e4f079332e69c02914612ce586a95ae0 (diff)
downloadarctica-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.vala42
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 ();
}
/*