glwindow: move g_main_context_push/pop_thread_default() to run()
authorMatthew Waters <matthew@centricular.com>
Mon, 28 Nov 2016 03:22:05 +0000 (14:22 +1100)
committerMatthew Waters <matthew@centricular.com>
Mon, 28 Nov 2016 09:09:06 +0000 (20:09 +1100)
Calling g_main_context_push_thread and then g_main_context_invoke()
(used by gst_gl_window_send_message_async()) in the same thread will
cause the invoked function to run immediately instead of being delayed.

This had implications for the creation of the OpenGL context not waiting
until the main loop had completely started up and as a result would
sometimes deadlock in short create/destroy scenarios.

https://bugzilla.gnome.org/show_bug.cgi?id=775171

gst-libs/gst/gl/gstglwindow.c

index 3ac2441e414e1232ca0a9a178f02114150616155..7a275e4f574cf0f3374defd277a3cd830ed425e9 100644 (file)
@@ -142,35 +142,12 @@ gst_gl_window_error_quark (void)
 static gboolean
 gst_gl_window_default_open (GstGLWindow * window, GError ** error)
 {
-  GstGLWindowPrivate *priv = window->priv;
-
-  if (g_main_context_get_thread_default ()) {
-    if (priv->main_context)
-      g_main_context_unref (priv->main_context);
-    if (priv->loop)
-      g_main_loop_unref (priv->loop);
-    priv->main_context = g_main_context_ref_thread_default ();
-    priv->loop = NULL;
-    priv->alive = TRUE;
-  } else {
-    g_main_context_push_thread_default (priv->main_context);
-  }
-
   return TRUE;
 }
 
 static void
 gst_gl_window_default_close (GstGLWindow * window)
 {
-  GstGLWindowPrivate *priv = window->priv;
-
-  if (!priv->loop) {
-    priv->alive = FALSE;
-    g_main_context_unref (priv->main_context);
-    priv->main_context = NULL;
-  } else {
-    g_main_context_pop_thread_default (priv->main_context);
-  }
 }
 
 static void
@@ -543,7 +520,29 @@ gst_gl_window_show (GstGLWindow * window)
 static void
 gst_gl_window_default_run (GstGLWindow * window)
 {
-  g_main_loop_run (window->priv->loop);
+  GstGLWindowPrivate *priv = window->priv;
+
+  if (g_main_context_get_thread_default ()) {
+    if (priv->main_context)
+      g_main_context_unref (priv->main_context);
+    if (priv->loop)
+      g_main_loop_unref (priv->loop);
+    priv->main_context = g_main_context_ref_thread_default ();
+    priv->loop = NULL;
+    priv->alive = TRUE;
+  } else {
+    g_main_context_push_thread_default (priv->main_context);
+  }
+
+  g_main_loop_run (priv->loop);
+
+  if (!priv->loop) {
+    priv->alive = FALSE;
+    g_main_context_unref (priv->main_context);
+    priv->main_context = NULL;
+  } else {
+    g_main_context_pop_thread_default (priv->main_context);
+  }
 }
 
 /**