gtk: Factor out a function to run a function on main thread
authorThibault Saunier <tsaunier@gnome.org>
Thu, 24 Sep 2015 09:37:04 +0000 (11:37 +0200)
committerThibault Saunier <tsaunier@gnome.org>
Thu, 24 Sep 2015 10:03:01 +0000 (12:03 +0200)
https://bugzilla.gnome.org/show_bug.cgi?id=755251

ext/gtk/Makefile.am
ext/gtk/gstgtkbasesink.c
ext/gtk/gstgtkutils.c [new file with mode: 0644]
ext/gtk/gstgtkutils.h [new file with mode: 0644]
ext/gtk/gtkgstglwidget.c

index f2e8c55..8484677 100644 (file)
@@ -16,6 +16,8 @@ sources = \
        gstgtkbasesink.h \
        gstgtksink.c \
        gstgtksink.h \
+       gstgtkutils.c \
+       gstgtkutils.h \
        gstplugin.c \
        $(NULL)
 
index 41bb7f2..9ce6f7c 100644 (file)
@@ -28,6 +28,7 @@
 #endif
 
 #include "gstgtkbasesink.h"
+#include "gstgtkutils.h"
 
 GST_DEBUG_CATEGORY (gst_debug_gtk_base_sink);
 #define GST_CAT_DEFAULT gst_debug_gtk_base_sink
@@ -77,53 +78,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstGtkBaseSink, gst_gtk_base_sink,
     GST_DEBUG_CATEGORY_INIT (gst_debug_gtk_base_sink,
         "gtkbasesink", 0, "Gtk Video Sink base class"));
 
-struct invoke_context
-{
-  GThreadFunc func;
-  gpointer data;
-  GMutex lock;
-  GCond cond;
-  gboolean fired;
-
-  gpointer res;
-};
-
-static gboolean
-_invoke_func (struct invoke_context *info)
-{
-  g_mutex_lock (&info->lock);
-  info->res = info->func (info->data);
-  info->fired = TRUE;
-  g_cond_signal (&info->cond);
-  g_mutex_unlock (&info->lock);
-
-  return G_SOURCE_REMOVE;
-}
-
-static gpointer
-_invoke_on_main (GThreadFunc func, gpointer data)
-{
-  GMainContext *main_context = g_main_context_default ();
-  struct invoke_context info;
-
-  g_mutex_init (&info.lock);
-  g_cond_init (&info.cond);
-  info.fired = FALSE;
-  info.func = func;
-  info.data = data;
-
-  g_main_context_invoke (main_context, (GSourceFunc) _invoke_func, &info);
-
-  g_mutex_lock (&info.lock);
-  while (!info.fired)
-    g_cond_wait (&info.cond, &info.lock);
-  g_mutex_unlock (&info.lock);
-
-  g_mutex_clear (&info.lock);
-  g_cond_clear (&info.cond);
-
-  return info.res;
-}
 
 static void
 gst_gtk_base_sink_class_init (GstGtkBaseSinkClass * klass)
@@ -264,7 +218,8 @@ gst_gtk_base_sink_get_property (GObject * object, guint prop_id,
       GST_OBJECT_UNLOCK (gtk_sink);
 
       if (!widget)
-        widget = _invoke_on_main ((GThreadFunc) gst_gtk_base_sink_get_widget,
+        widget =
+            gst_gtk_invoke_on_main ((GThreadFunc) gst_gtk_base_sink_get_widget,
             gtk_sink);
 
       g_value_set_object (value, widget);
@@ -366,8 +321,8 @@ gst_gtk_base_sink_start_on_main (GstBaseSink * bsink)
 static gboolean
 gst_gtk_base_sink_start (GstBaseSink * bsink)
 {
-  return ! !_invoke_on_main ((GThreadFunc) gst_gtk_base_sink_start_on_main,
-      bsink);
+  return ! !gst_gtk_invoke_on_main ((GThreadFunc)
+      gst_gtk_base_sink_start_on_main, bsink);
 }
 
 static gboolean
@@ -387,12 +342,12 @@ gst_gtk_base_sink_stop_on_main (GstBaseSink * bsink)
 static gboolean
 gst_gtk_base_sink_stop (GstBaseSink * bsink)
 {
-  return ! !_invoke_on_main ((GThreadFunc) gst_gtk_base_sink_stop_on_main,
-      bsink);
+  return ! !gst_gtk_invoke_on_main ((GThreadFunc)
+      gst_gtk_base_sink_stop_on_main, bsink);
 }
 
 static void
-gst_gtk_widget_show_all_and_unref (GtkWidget * widget)
+gst_gtk_widget_show_all_and_unref (GtkWidget *widget)
 {
   gtk_widget_show_all (widget);
   g_object_unref (widget);
@@ -423,8 +378,7 @@ gst_gtk_base_sink_change_state (GstElement * element, GstStateChange transition)
       GST_OBJECT_UNLOCK (gtk_sink);
 
       if (window)
-        _invoke_on_main ((GThreadFunc) gst_gtk_widget_show_all_and_unref,
-            window);
+        gst_gtk_invoke_on_main ((GThreadFunc) gst_gtk_widget_show_all_and_unref, window);
 
       break;
     }
diff --git a/ext/gtk/gstgtkutils.c b/ext/gtk/gstgtkutils.c
new file mode 100644 (file)
index 0000000..c730f01
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
+ * Copyright (C) 2015 Thibault Saunier <tsaunier@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "gstgtkutils.h"
+
+struct invoke_context
+{
+  GThreadFunc func;
+  gpointer data;
+  GMutex lock;
+  GCond cond;
+  gboolean fired;
+
+  gpointer res;
+};
+
+static gboolean
+gst_gtk_invoke_func (struct invoke_context *info)
+{
+  g_mutex_lock (&info->lock);
+  info->res = info->func (info->data);
+  info->fired = TRUE;
+  g_cond_signal (&info->cond);
+  g_mutex_unlock (&info->lock);
+
+  return G_SOURCE_REMOVE;
+}
+
+gpointer
+gst_gtk_invoke_on_main (GThreadFunc func, gpointer data)
+{
+  GMainContext *main_context = g_main_context_default ();
+  struct invoke_context info;
+
+  g_mutex_init (&info.lock);
+  g_cond_init (&info.cond);
+  info.fired = FALSE;
+  info.func = func;
+  info.data = data;
+
+  g_main_context_invoke (main_context, (GSourceFunc) gst_gtk_invoke_func,
+      &info);
+
+  g_mutex_lock (&info.lock);
+  while (!info.fired)
+    g_cond_wait (&info.cond, &info.lock);
+  g_mutex_unlock (&info.lock);
+
+  g_mutex_clear (&info.lock);
+  g_cond_clear (&info.cond);
+
+  return info.res;
+}
diff --git a/ext/gtk/gstgtkutils.h b/ext/gtk/gstgtkutils.h
new file mode 100644 (file)
index 0000000..7584ae2
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * GStreamer
+ * Copyright (C) 2015 Matthew Waters <matthew@centricular.com>
+ * Copyright (C) 2015 Thibault Saunier <tsaunier@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_GTK_UTILS_H__
+#define __GST_GTK_UTILS_H__
+
+#include <glib.h>
+
+gpointer gst_gtk_invoke_on_main (GThreadFunc func, gpointer data);
+
+#endif /* __GST_GTK_UTILS_H__ */
index b16725f..7b3f37f 100644 (file)
@@ -25,6 +25,7 @@
 #include <stdio.h>
 
 #include "gtkgstglwidget.h"
+#include "gstgtkutils.h"
 #include <gst/video/video.h>
 
 #if GST_GL_HAVE_WINDOW_X11 && GST_GL_HAVE_PLATFORM_GLX && defined (GDK_WINDOWING_X11)
@@ -278,52 +279,6 @@ done:
   return FALSE;
 }
 
-typedef void (*ThreadFunc) (gpointer data);
-
-struct invoke_context
-{
-  ThreadFunc func;
-  gpointer data;
-  GMutex lock;
-  GCond cond;
-  gboolean fired;
-};
-
-static gboolean
-_invoke_func (struct invoke_context *info)
-{
-  g_mutex_lock (&info->lock);
-  info->func (info->data);
-  info->fired = TRUE;
-  g_cond_signal (&info->cond);
-  g_mutex_unlock (&info->lock);
-
-  return G_SOURCE_REMOVE;
-}
-
-static void
-_invoke_on_main (ThreadFunc func, gpointer data)
-{
-  GMainContext *main_context = g_main_context_default ();
-  struct invoke_context info;
-
-  g_mutex_init (&info.lock);
-  g_cond_init (&info.cond);
-  info.fired = FALSE;
-  info.func = func;
-  info.data = data;
-
-  g_main_context_invoke (main_context, (GSourceFunc) _invoke_func, &info);
-
-  g_mutex_lock (&info.lock);
-  while (!info.fired)
-    g_cond_wait (&info.cond, &info.lock);
-  g_mutex_unlock (&info.lock);
-
-  g_mutex_clear (&info.lock);
-  g_cond_clear (&info.cond);
-}
-
 static void
 _reset_gl (GtkGstGLWidget * gst_widget)
 {
@@ -380,7 +335,7 @@ gtk_gst_gl_widget_finalize (GObject * object)
   GtkGstBaseWidget *base_widget = GTK_GST_BASE_WIDGET (object);
 
   if (priv->other_context)
-    _invoke_on_main ((ThreadFunc) _reset_gl, base_widget);
+    gst_gtk_invoke_on_main ((GThreadFunc) _reset_gl, base_widget);
 
   if (priv->context)
     gst_object_unref (priv->context);
@@ -534,7 +489,7 @@ gtk_gst_gl_widget_init_winsys (GtkGstGLWidget * gst_widget)
 
   if (!priv->other_context) {
     GTK_GST_BASE_WIDGET_UNLOCK (gst_widget);
-    _invoke_on_main ((ThreadFunc) _get_gl_context, gst_widget);
+    gst_gtk_invoke_on_main ((GThreadFunc) _get_gl_context, gst_widget);
     GTK_GST_BASE_WIDGET_LOCK (gst_widget);
   }