[mutter] later: Make MetaCompositor the owner of the MetaLaters state



commit 2e7d02f1ce8cb8eba15968c7facd815a7ce43080
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Mar 3 09:32:33 2020 +0100

    later: Make MetaCompositor the owner of the MetaLaters state
    
    Since the order of destruction during MetaDisplay tear down is a bit
    unordered, there are pieces that try to destruct its compositing
    dependent pieces (i.e. queued MetaLater callbacks) after MetaCompositor
    has been cleaned up, meaning we need to put some slightly awkward NULL
    checks to avoid crashing.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/798

 src/compositor/compositor-private.h |  4 +++
 src/compositor/compositor.c         | 16 +++++++++++
 src/compositor/meta-later-private.h | 27 +++++++++++++++++++
 src/compositor/meta-later.c         | 44 +++++++++++++++++++++++++-----
 src/meta/meson.build                |  1 +
 src/meta/meta-later.h               | 53 +++++++++++++++++++++++++++++++++++++
 src/meta/util.h                     | 31 +---------------------
 7 files changed, 139 insertions(+), 37 deletions(-)
---
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index eb536284f..1917aa03d 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -14,6 +14,8 @@
 /* Wait 2ms after vblank before starting to draw next frame */
 #define META_SYNC_DELAY 2
 
+typedef struct _MetaLaters MetaLaters;
+
 struct _MetaCompositorClass
 {
   GObjectClass parent_class;
@@ -71,4 +73,6 @@ ClutterStage * meta_compositor_get_stage (MetaCompositor *compositor);
 
 gboolean meta_compositor_is_switching_workspace (MetaCompositor *compositor);
 
+MetaLaters * meta_compositor_get_laters (MetaCompositor *compositor);
+
 #endif /* META_COMPOSITOR_PRIVATE_H */
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 5681d7478..06b5ee6a3 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -62,6 +62,7 @@
 #include "backends/x11/meta-stage-x11.h"
 #include "clutter/clutter-mutter.h"
 #include "cogl/cogl.h"
+#include "compositor/meta-later-private.h"
 #include "compositor/meta-window-actor-x11.h"
 #include "compositor/meta-window-actor-wayland.h"
 #include "compositor/meta-window-actor-private.h"
@@ -131,6 +132,8 @@ typedef struct _MetaCompositorPrivate
   int switch_workspace_in_progress;
 
   MetaPluginManager *plugin_mgr;
+
+  MetaLaters *laters;
 } MetaCompositorPrivate;
 
 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaCompositor, meta_compositor,
@@ -1243,6 +1246,8 @@ meta_compositor_init (MetaCompositor *compositor)
                                            meta_post_paint_func,
                                            compositor,
                                            NULL);
+
+  priv->laters = meta_laters_new ();
 }
 
 static void
@@ -1252,6 +1257,8 @@ meta_compositor_dispose (GObject *object)
   MetaCompositorPrivate *priv =
     meta_compositor_get_instance_private (compositor);
 
+  g_clear_pointer (&priv->laters, meta_laters_free);
+
   g_clear_signal_handler (&priv->stage_after_paint_id, priv->stage);
   g_clear_signal_handler (&priv->stage_presented_id, priv->stage);
 
@@ -1610,3 +1617,12 @@ meta_compositor_is_switching_workspace (MetaCompositor *compositor)
 
   return priv->switch_workspace_in_progress > 0;
 }
+
+MetaLaters *
+meta_compositor_get_laters (MetaCompositor *compositor)
+{
+  MetaCompositorPrivate *priv =
+    meta_compositor_get_instance_private (compositor);
+
+  return priv->laters;
+}
diff --git a/src/compositor/meta-later-private.h b/src/compositor/meta-later-private.h
new file mode 100644
index 000000000..b1c88766f
--- /dev/null
+++ b/src/compositor/meta-later-private.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_LATER_PRIVATE_H
+#define META_LATER_PRIVATE_H
+
+typedef struct _MetaLaters MetaLaters;
+
+MetaLaters * meta_laters_new (void);
+
+void meta_laters_free (MetaLaters *laters);
+
+#endif /* META_LATER_PRIVATE_H */
diff --git a/src/compositor/meta-later.c b/src/compositor/meta-later.c
index 1b71f58bb..aaa0f11d4 100644
--- a/src/compositor/meta-later.c
+++ b/src/compositor/meta-later.c
@@ -19,8 +19,12 @@
 
 #include "config.h"
 
+#include "compositor/meta-later-private.h"
+
 #include "cogl/cogl.h"
-#include "meta/util.h"
+#include "compositor/compositor-private.h"
+#include "core/display-private.h"
+#include "meta/meta-later.h"
 
 typedef struct _MetaLater
 {
@@ -36,8 +40,6 @@ typedef struct _MetaLater
   gboolean run_once;
 } MetaLater;
 
-typedef struct _MetaLaters MetaLaters;
-
 #define META_LATER_N_TYPES (META_LATER_IDLE + 1)
 
 struct _MetaLaters
@@ -50,8 +52,6 @@ struct _MetaLaters
   guint repaint_func;
 };
 
-static MetaLaters _laters;
-
 static MetaLater *
 meta_later_ref (MetaLater *later)
 {
@@ -292,7 +292,11 @@ meta_later_add (MetaLaterType  when,
                 gpointer       data,
                 GDestroyNotify notify)
 {
-  return meta_laters_add (&_laters, when, func, data, notify);
+  MetaDisplay *display = meta_get_display ();
+  MetaCompositor *compositor = display->compositor;
+
+  return meta_laters_add (meta_compositor_get_laters (compositor),
+                          when, func, data, notify);
 }
 
 static void
@@ -317,5 +321,31 @@ meta_laters_remove (MetaLaters   *laters,
 void
 meta_later_remove (unsigned int later_id)
 {
-  meta_laters_remove (&_laters, later_id);
+  MetaDisplay *display = meta_get_display ();
+  MetaCompositor *compositor = display->compositor;
+
+  if (!compositor)
+    return;
+
+  meta_laters_remove (meta_compositor_get_laters (compositor), later_id);
+}
+
+MetaLaters *
+meta_laters_new (void)
+{
+  return g_new0 (MetaLaters, 1);
+}
+
+void
+meta_laters_free (MetaLaters *laters)
+{
+  unsigned int i;
+
+  for (i = 0; i < G_N_ELEMENTS (laters->laters); i++)
+    g_slist_free_full (laters->laters[i], (GDestroyNotify) meta_later_unref);
+
+  g_clear_object (&laters->timeline);
+  if (laters->repaint_func)
+    clutter_threads_remove_repaint_func (laters->repaint_func);
+  g_free (laters);
 }
diff --git a/src/meta/meson.build b/src/meta/meson.build
index 14caec58d..279a6d9b1 100644
--- a/src/meta/meson.build
+++ b/src/meta/meson.build
@@ -19,6 +19,7 @@ mutter_public_headers = [
   'meta-idle-monitor.h',
   'meta-inhibit-shortcuts-dialog.h',
   'meta-launch-context.h',
+  'meta-later.h',
   'meta-monitor-manager.h',
   'meta-plugin.h',
   'meta-remote-access-controller.h',
diff --git a/src/meta/meta-later.h b/src/meta/meta-later.h
new file mode 100644
index 000000000..4464fc3bd
--- /dev/null
+++ b/src/meta/meta-later.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2001 Havoc Pennington
+ * Copyright (C) 2005 Elijah Newren
+ * Copyright (C) 2020 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_LATER_H
+#define META_LATER_H
+
+/**
+ * MetaLaterType:
+ * @META_LATER_RESIZE: call in a resize processing phase that is done
+ *   before GTK+ repainting (including window borders) is done.
+ * @META_LATER_CALC_SHOWING: used by Mutter to compute which windows should be mapped
+ * @META_LATER_CHECK_FULLSCREEN: used by Mutter to see if there's a fullscreen window
+ * @META_LATER_SYNC_STACK: used by Mutter to send it's idea of the stacking order to the server
+ * @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
+ * @META_LATER_IDLE: call at a very low priority (can be blocked
+ *    by running animations or redrawing applications)
+ **/
+typedef enum
+{
+  META_LATER_RESIZE,
+  META_LATER_CALC_SHOWING,
+  META_LATER_CHECK_FULLSCREEN,
+  META_LATER_SYNC_STACK,
+  META_LATER_BEFORE_REDRAW,
+  META_LATER_IDLE
+} MetaLaterType;
+
+META_EXPORT
+guint meta_later_add    (MetaLaterType  when,
+                         GSourceFunc    func,
+                         gpointer       data,
+                         GDestroyNotify notify);
+
+META_EXPORT
+void  meta_later_remove (guint          later_id);
+
+#endif /* META_LATER_H */
diff --git a/src/meta/util.h b/src/meta/util.h
index 86c53bb7c..c413622db 100644
--- a/src/meta/util.h
+++ b/src/meta/util.h
@@ -27,6 +27,7 @@
 #include <glib-object.h>
 
 #include <meta/common.h>
+#include <meta/meta-later.h>
 
 META_EXPORT
 gboolean meta_is_verbose  (void);
@@ -185,36 +186,6 @@ GPid meta_show_dialog (const char *type,
 
 #endif /* !WITH_VERBOSE_MODE */
 
-/**
- * MetaLaterType:
- * @META_LATER_RESIZE: call in a resize processing phase that is done
- *   before GTK+ repainting (including window borders) is done.
- * @META_LATER_CALC_SHOWING: used by Mutter to compute which windows should be mapped
- * @META_LATER_CHECK_FULLSCREEN: used by Mutter to see if there's a fullscreen window
- * @META_LATER_SYNC_STACK: used by Mutter to send it's idea of the stacking order to the server
- * @META_LATER_BEFORE_REDRAW: call before the stage is redrawn
- * @META_LATER_IDLE: call at a very low priority (can be blocked
- *    by running animations or redrawing applications)
- **/
-typedef enum
-{
-  META_LATER_RESIZE,
-  META_LATER_CALC_SHOWING,
-  META_LATER_CHECK_FULLSCREEN,
-  META_LATER_SYNC_STACK,
-  META_LATER_BEFORE_REDRAW,
-  META_LATER_IDLE
-} MetaLaterType;
-
-META_EXPORT
-guint meta_later_add    (MetaLaterType  when,
-                         GSourceFunc    func,
-                         gpointer       data,
-                         GDestroyNotify notify);
-
-META_EXPORT
-void  meta_later_remove (guint          later_id);
-
 typedef enum
 {
   META_LOCALE_DIRECTION_LTR,


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