[mutter] cogl/xlib-renderer: Save Xlib renderer data in custom winsys pointer



commit 61c173b777bc8b0c26ea6b1b73fef450f3ae1927
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Fri May 17 14:28:01 2019 -0500

    cogl/xlib-renderer: Save Xlib renderer data in custom winsys pointer
    
    XLib renderer saves its data as the object cogl user data, however this data
    is free'd as part of the object destruction that happens before free'ing the
    renderer in _cogl_renderer_free(), from where we're calling the renderer
    disconnect vfunc.
    Thus in _cogl_xlib_renderer_disconnect() we happen to get an invalid pointer to
    CoglXlibRenderer and we try access to it in order to close the X11 display.
    
    This causes all the cogl tests to crash when G_SLICE=always-malloc is set and
    when using MALLOC_CHECK_.
    
    Fix this using the renderer winsys custom data instead of using cogl object data
    for storing the CoglXlibRenderer, and handling the destruction of it manually.
    
    As bonus this also makes access to the renderer data faster.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/581

 cogl/cogl/cogl-xlib-renderer.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)
---
diff --git a/cogl/cogl/cogl-xlib-renderer.c b/cogl/cogl/cogl-xlib-renderer.c
index 68dfbe147..ea1a47e46 100644
--- a/cogl/cogl/cogl-xlib-renderer.c
+++ b/cogl/cogl/cogl-xlib-renderer.c
@@ -54,41 +54,27 @@ static char *_cogl_x11_display_name = NULL;
 static GList *_cogl_xlib_renderers = NULL;
 
 static void
-destroy_xlib_renderer_data (void *user_data)
+_xlib_renderer_data_free (CoglXlibRenderer *data)
 {
-  CoglXlibRenderer *data = user_data;
-
   if (data->xvisinfo)
     XFree (data->xvisinfo);
 
-  g_slice_free (CoglXlibRenderer, user_data);
+  g_slice_free (CoglXlibRenderer, data);
 }
 
 CoglXlibRenderer *
 _cogl_xlib_renderer_get_data (CoglRenderer *renderer)
 {
-  static CoglUserDataKey key;
-  CoglXlibRenderer *data;
-
   /* Constructs a CoglXlibRenderer struct on demand and attaches it to
      the object using user data. It's done this way instead of using a
      subclassing hierarchy in the winsys data because all EGL winsys's
      need the EGL winsys data but only one of them wants the Xlib
      data. */
 
-  data = cogl_object_get_user_data (COGL_OBJECT (renderer), &key);
-
-  if (data == NULL)
-    {
-      data = g_slice_new0 (CoglXlibRenderer);
+  if (!renderer->custom_winsys_user_data)
+    renderer->custom_winsys_user_data = g_slice_new0 (CoglXlibRenderer);
 
-      cogl_object_set_user_data (COGL_OBJECT (renderer),
-                                 &key,
-                                 data,
-                                 destroy_xlib_renderer_data);
-    }
-
-  return data;
+  return renderer->custom_winsys_user_data;
 }
 
 static void
@@ -570,6 +556,8 @@ _cogl_xlib_renderer_disconnect (CoglRenderer *renderer)
   if (!renderer->foreign_xdpy && xlib_renderer->xdpy)
     XCloseDisplay (xlib_renderer->xdpy);
 
+  g_clear_pointer (&renderer->custom_winsys_user_data, _xlib_renderer_data_free);
+
   unregister_xlib_renderer (renderer);
 }
 


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