summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2016-11-28 14:19:18 +1100
committerMatthew Waters <matthew@centricular.com>2016-11-28 20:09:06 +1100
commitf7e4417f52c5e37aaa45ca1ce2fd09dd3665f975 (patch)
treedf5b70f39667d6283bbf18673ed8325773c25e60
parentf25557c023662634540e94d658a130267010cf25 (diff)
downloadgstreamer-plugins-bad-f7e4417f52c5e37aaa45ca1ce2fd09dd3665f975.tar.gz
glcontext: fix race between creation/shutdown
626bcccff96f624f59c5212b3e21e472240171fd removed some locks that allowed the main loop quit to occur before the context was fully created. 2776cef25d2a98668b73272aecfe77e684e6627e attempted to readd them but missed the scop of the quit() call. Also remove the use of g_thread_join() as that's not safe to use when it's possible to lose the last reference from the GL thread. https://bugzilla.gnome.org/show_bug.cgi?id=775171
-rw-r--r--gst-libs/gst/gl/gstglcontext.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/gst-libs/gst/gl/gstglcontext.c b/gst-libs/gst/gl/gstglcontext.c
index eb46e6ccd..975f7d80c 100644
--- a/gst-libs/gst/gl/gstglcontext.c
+++ b/gst-libs/gst/gl/gstglcontext.c
@@ -201,6 +201,7 @@ struct _GstGLContextPrivate
/* conditions */
GMutex render_lock;
GCond create_cond;
+ GCond destroy_cond;
gboolean created;
gboolean alive;
@@ -272,6 +273,7 @@ gst_gl_context_init (GstGLContext * context)
g_mutex_init (&context->priv->render_lock);
g_cond_init (&context->priv->create_cond);
+ g_cond_init (&context->priv->destroy_cond);
context->priv->created = FALSE;
g_weak_ref_init (&context->priv->other_context_ref, NULL);
@@ -656,22 +658,20 @@ gst_gl_context_finalize (GObject * object)
gst_gl_window_set_resize_callback (context->window, NULL, NULL, NULL);
gst_gl_window_set_draw_callback (context->window, NULL, NULL, NULL);
+ g_mutex_lock (&context->priv->render_lock);
if (context->priv->alive) {
GST_INFO_OBJECT (context, "send quit gl window loop");
gst_gl_window_quit (context->window);
GST_INFO_OBJECT (context, "joining gl thread");
- g_mutex_lock (&context->priv->render_lock);
- if (context->priv->alive) {
- GThread *t = context->priv->gl_thread;
- g_mutex_unlock (&context->priv->render_lock);
- g_thread_join (t);
- } else {
- g_mutex_unlock (&context->priv->render_lock);
- }
+ while (context->priv->alive)
+ 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;
}
+ g_mutex_unlock (&context->priv->render_lock);
gst_gl_window_set_close_callback (context->window, NULL, NULL, NULL);
gst_object_unref (context->window);
@@ -690,6 +690,7 @@ gst_gl_context_finalize (GObject * object)
g_mutex_clear (&context->priv->render_lock);
g_cond_clear (&context->priv->create_cond);
+ g_cond_clear (&context->priv->destroy_cond);
g_free (context->priv->gl_exts);
g_weak_ref_clear (&context->priv->other_context_ref);
@@ -1290,6 +1291,7 @@ gst_gl_context_create_thread (GstGLContext * context)
}
context->priv->created = FALSE;
+ g_cond_signal (&context->priv->destroy_cond);
g_mutex_unlock (&context->priv->render_lock);
return NULL;