diff options
author | fvanzile <frank@fvanzile.com> | 2017-02-23 15:42:08 -0800 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2017-05-29 10:49:29 +0300 |
commit | 63627a8c715ef6a762d40f640a1d2afd864cbd11 (patch) | |
tree | 0afa580b5be84e9aba510aac7736751c14814ef5 | |
parent | 8f270a5b68a6bfd6eb0392fb7031fb1f0d6ecbc0 (diff) | |
download | gstreamer-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.c | 54 |
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 (¤t_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 (¤t_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; } |