summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfvanzile <frank@fvanzile.com>2017-02-23 15:42:08 -0800
committerSebastian Dröge <sebastian@centricular.com>2017-05-29 10:49:29 +0300
commit63627a8c715ef6a762d40f640a1d2afd864cbd11 (patch)
tree0afa580b5be84e9aba510aac7736751c14814ef5
parent8f270a5b68a6bfd6eb0392fb7031fb1f0d6ecbc0 (diff)
downloadgstreamer-plugins-bad-63627a8c715ef6a762d40f640a1d2afd864cbd11.tar.gz
glcontext: keep a ref to the active thread
With the macOS/iOS implementations, the active thread can change multiple times over the life of a pipeline which would expose a race in the thread tracking. Fix by taking a ref on the active thread while the context is active. https://bugzilla.gnome.org/show_bug.cgi?id=779202
-rw-r--r--gst-libs/gst/gl/gstglcontext.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/gst-libs/gst/gl/gstglcontext.c b/gst-libs/gst/gl/gstglcontext.c
index 9af5e1cc8..83b50c65c 100644
--- a/gst-libs/gst/gl/gstglcontext.c
+++ b/gst-libs/gst/gl/gstglcontext.c
@@ -673,19 +673,37 @@ gst_gl_context_finalize (GObject * object)
g_cond_wait (&context->priv->destroy_cond, &context->priv->render_lock);
GST_INFO_OBJECT (context, "gl thread joined");
- g_thread_unref (context->priv->gl_thread);
- context->priv->gl_thread = NULL;
+ if (context->priv->gl_thread) {
+ g_thread_unref (context->priv->gl_thread);
+ context->priv->gl_thread = NULL;
+ }
}
g_mutex_unlock (&context->priv->render_lock);
gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
gst_object_unref (context->window);
+ context->window = NULL;
}
- if (context->priv->sharegroup)
+ if (context->priv->active_thread) {
+ g_thread_unref (context->priv->active_thread);
+ context->priv->active_thread = NULL;
+ }
+
+ if (context->priv->gl_thread) {
+ g_thread_unref (context->priv->gl_thread);
+ context->priv->gl_thread = NULL;
+ }
+
+ if (context->priv->sharegroup) {
_context_share_group_unref (context->priv->sharegroup);
+ context->priv->sharegroup = NULL;
+ }
- gst_object_unref (context->display);
+ if (context->display) {
+ gst_object_unref (context->display);
+ context->display = NULL;
+ }
if (context->gl_vtable) {
g_slice_free (GstGLFuncs, context->gl_vtable);
@@ -734,10 +752,18 @@ gst_gl_context_activate (GstGLContext * context, gboolean activate)
result = context_class->activate (context, activate);
if (result && activate) {
- context->priv->active_thread = g_thread_self ();
+ GThread *old_thread = context->priv->active_thread;
+ context->priv->active_thread = g_thread_ref (g_thread_self ());
+ if (old_thread) {
+ g_thread_unref (old_thread);
+ }
+
g_private_set (&current_context_key, context);
} else {
- context->priv->active_thread = NULL;
+ if (context->priv->active_thread) {
+ g_thread_unref (context->priv->active_thread);
+ context->priv->active_thread = NULL;
+ }
g_private_set (&current_context_key, NULL);
}
GST_OBJECT_UNLOCK (context);
@@ -1767,10 +1793,18 @@ gst_gl_wrapped_context_get_gl_platform (GstGLContext * context)
static gboolean
gst_gl_wrapped_context_activate (GstGLContext * context, gboolean activate)
{
- if (activate)
- context->priv->gl_thread = g_thread_self ();
- else
- context->priv->gl_thread = NULL;
+ if (activate) {
+ GThread *old_thread = context->priv->gl_thread;
+ context->priv->gl_thread = g_thread_ref (g_thread_self ());
+ if (old_thread) {
+ g_thread_unref (old_thread);
+ }
+ } else {
+ if (context->priv->gl_thread) {
+ g_thread_unref (context->priv->gl_thread);
+ context->priv->gl_thread = NULL;
+ }
+ }
return TRUE;
}