[mutter] context: Add explicit state tracking



commit 2deb751fd98cf88d67283814a955dd07971919b7
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Wed Mar 3 23:02:50 2021 +0100

    context: Add explicit state tracking
    
    This will help finding out when things happen in the wrong order.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1861>

 src/core/meta-context.c | 62 +++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 58 insertions(+), 4 deletions(-)
---
diff --git a/src/core/meta-context.c b/src/core/meta-context.c
index 458190e390..3441c60b56 100644
--- a/src/core/meta-context.c
+++ b/src/core/meta-context.c
@@ -46,6 +46,16 @@ enum
 
 static GParamSpec *obj_props[N_PROPS];
 
+typedef enum _MetaContextState
+{
+  META_CONTEXT_STATE_INIT,
+  META_CONTEXT_STATE_CONFIGURED,
+  META_CONTEXT_STATE_SETUP,
+  META_CONTEXT_STATE_STARTED,
+  META_CONTEXT_STATE_RUNNING,
+  META_CONTEXT_STATE_TERMINATED,
+} MetaContextState;
+
 typedef struct _MetaContextPrivate
 {
   char *name;
@@ -53,6 +63,8 @@ typedef struct _MetaContextPrivate
   GType plugin_gtype;
   char *gnome_wm_keybindings;
 
+  MetaContextState state;
+
   GOptionContext *option_context;
 
   MetaBackend *backend;
@@ -74,6 +86,8 @@ meta_context_add_option_entries (MetaContext        *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_INIT);
+
   g_option_context_add_main_entries (priv->option_context,
                                      entries,
                                      translation_domain);
@@ -85,6 +99,7 @@ meta_context_add_option_group (MetaContext  *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_INIT);
   g_return_if_fail (priv->option_context);
 
   g_option_context_add_group (priv->option_context, group);
@@ -96,6 +111,7 @@ meta_context_set_plugin_gtype (MetaContext *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_return_if_fail (priv->state <= META_CONTEXT_STATE_CONFIGURED);
   g_return_if_fail (!priv->plugin_name);
 
   priv->plugin_gtype = plugin_gtype;
@@ -107,6 +123,7 @@ meta_context_set_plugin_name (MetaContext *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_return_if_fail (priv->state <= META_CONTEXT_STATE_CONFIGURED);
   g_return_if_fail (priv->plugin_gtype == G_TYPE_NONE);
 
   priv->plugin_name = g_strdup (plugin_name);
@@ -118,6 +135,8 @@ meta_context_set_gnome_wm_keybindings (MetaContext *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_return_if_fail (priv->state <= META_CONTEXT_STATE_CONFIGURED);
+
   g_clear_pointer (&priv->gnome_wm_keybindings, g_free);
   priv->gnome_wm_keybindings = g_strdup (wm_keybindings);
 }
@@ -133,6 +152,11 @@ meta_context_get_gnome_wm_keybindings (MetaContext *context)
 void
 meta_context_notify_ready (MetaContext *context)
 {
+  MetaContextPrivate *priv = meta_context_get_instance_private (context);
+
+  g_return_if_fail (priv->state == META_CONTEXT_STATE_STARTED ||
+                    priv->state == META_CONTEXT_STATE_RUNNING);
+
   META_CONTEXT_GET_CLASS (context)->notify_ready (context);
 }
 
@@ -214,10 +238,16 @@ meta_context_configure (MetaContext   *context,
                         char        ***argv,
                         GError       **error)
 {
+  MetaContextPrivate *priv = meta_context_get_instance_private (context);
   MetaCompositorType compositor_type;
 
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_INIT);
+
   if (!META_CONTEXT_GET_CLASS (context)->configure (context, argc, argv, error))
-    return FALSE;
+    {
+      priv->state = META_CONTEXT_STATE_TERMINATED;
+      return FALSE;
+    }
 
   compositor_type = meta_context_get_compositor_type (context);
   switch (compositor_type)
@@ -230,6 +260,8 @@ meta_context_configure (MetaContext   *context,
       break;
     }
 
+  priv->state = META_CONTEXT_STATE_CONFIGURED;
+
   return TRUE;
 }
 
@@ -320,8 +352,11 @@ meta_context_setup (MetaContext  *context,
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
   MetaCompositorType compositor_type;
 
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_CONFIGURED);
+
   if (!priv->plugin_name && priv->plugin_gtype == G_TYPE_NONE)
     {
+      priv->state = META_CONTEXT_STATE_TERMINATED;
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "No compositor plugin set");
       return FALSE;
@@ -344,7 +379,14 @@ meta_context_setup (MetaContext  *context,
 
   init_introspection (context);
 
-  return META_CONTEXT_GET_CLASS (context)->setup (context, error);
+  if (!META_CONTEXT_GET_CLASS (context)->setup (context, error))
+    {
+      priv->state = META_CONTEXT_STATE_TERMINATED;
+      return FALSE;
+    }
+
+  priv->state = META_CONTEXT_STATE_SETUP;
+  return TRUE;
 }
 
 gboolean
@@ -353,6 +395,8 @@ meta_context_start (MetaContext  *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_SETUP);
+
   meta_prefs_init ();
 
 #ifdef HAVE_WAYLAND
@@ -363,10 +407,15 @@ meta_context_start (MetaContext  *context,
 
   priv->display = meta_display_new (context, error);
   if (!priv->display)
-    return FALSE;
+    {
+      priv->state = META_CONTEXT_STATE_TERMINATED;
+      return FALSE;
+    }
 
   priv->main_loop = g_main_loop_new (NULL, FALSE);
 
+  priv->state = META_CONTEXT_STATE_STARTED;
+
   return TRUE;
 }
 
@@ -376,14 +425,18 @@ meta_context_run_main_loop (MetaContext  *context,
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_STARTED);
   if (!priv->main_loop)
     {
+      priv->state = META_CONTEXT_STATE_TERMINATED;
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "Tried to run main loop without having started");
       return FALSE;
     }
 
+  priv->state = META_CONTEXT_STATE_RUNNING;
   g_main_loop_run (priv->main_loop);
+  priv->state = META_CONTEXT_STATE_TERMINATED;
   g_clear_pointer (&priv->main_loop, g_main_loop_unref);
 
   if (priv->termination_error)
@@ -400,7 +453,8 @@ meta_context_terminate (MetaContext *context)
 {
   MetaContextPrivate *priv = meta_context_get_instance_private (context);
 
-  g_return_if_fail (g_main_loop_is_running (priv->main_loop));
+  g_warn_if_fail (priv->state == META_CONTEXT_STATE_RUNNING);
+  g_warn_if_fail (g_main_loop_is_running (priv->main_loop));
 
   g_main_loop_quit (priv->main_loop);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]