summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2016-10-05 18:32:09 +1100
committerMatthew Waters <matthew@centricular.com>2016-10-05 18:32:09 +1100
commit9ad4c67578e95a48e2969c8272e2c94ff3fc50b5 (patch)
tree0f7357b5526b0c408b86713bad269215e8d4b99c /gst-libs
parent1ffe22240a054d7d109d4a398faea498b813c127 (diff)
downloadgstreamer-plugins-bad-9ad4c67578e95a48e2969c8272e2c94ff3fc50b5.tar.gz
glwindow: don't use g_thread_join() to join the navigation thread
Using g_thread_join() in _finalize() handlers may result in a deadlock joining the current thread when the last reference is held by a signal handler. e.g.: error 'Resource deadlock avoided' during 'pthread_join (pt->system_thread, NULL)' The backtrace looks like this: [...] g_thread_join () gst_gl_window_finalize () gst_gl_window_x11_finalize () g_object_unref () g_value_unset () g_signal_emit_valist () g_signal_emit () gst_gl_window_send_mouse_event () gst_gl_window_mouse_event_cb () g_main_dispatch () [..] g_main_loop_run () gst_gl_window_navigation_thread () g_thread_proxy () start_thread () clone ()
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/gl/gstglwindow.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c
index b74d39755..0588f1d65 100644
--- a/gst-libs/gst/gl/gstglwindow.c
+++ b/gst-libs/gst/gl/gstglwindow.c
@@ -101,6 +101,7 @@ struct _GstGLWindowPrivate
GMainLoop *navigation_loop;
GMutex nav_lock;
GCond nav_create_cond;
+ GCond nav_destroy_cond;
gboolean nav_alive;
GMutex sync_message_lock;
GCond sync_message_cond;
@@ -335,12 +336,16 @@ gst_gl_window_finalize (GObject * object)
GstGLWindowPrivate *priv = window->priv;
GST_INFO ("quit navigation loop");
+
+ g_mutex_lock (&window->priv->nav_lock);
if (window->priv->navigation_loop) {
g_main_loop_quit (window->priv->navigation_loop);
/* wait until navigation thread finished */
- g_thread_join (window->priv->navigation_thread);
+ while (window->priv->nav_alive)
+ g_cond_wait (&window->priv->nav_destroy_cond, &window->priv->nav_lock);
window->priv->navigation_thread = NULL;
}
+ g_mutex_unlock (&window->priv->nav_lock);
if (priv->loop)
g_main_loop_unref (priv->loop);
@@ -353,6 +358,7 @@ gst_gl_window_finalize (GObject * object)
g_mutex_clear (&window->lock);
g_mutex_clear (&window->priv->nav_lock);
g_cond_clear (&window->priv->nav_create_cond);
+ g_cond_clear (&window->priv->nav_destroy_cond);
g_mutex_clear (&window->priv->sync_message_lock);
g_cond_clear (&window->priv->sync_message_cond);
gst_object_unref (window->display);
@@ -939,6 +945,7 @@ gst_gl_window_navigation_thread (GstGLWindow * window)
g_main_loop_run (window->priv->navigation_loop);
+ g_mutex_lock (&window->priv->nav_lock);
g_main_context_pop_thread_default (window->priv->navigation_context);
g_main_loop_unref (window->priv->navigation_loop);
@@ -946,6 +953,10 @@ gst_gl_window_navigation_thread (GstGLWindow * window)
window->priv->navigation_loop = NULL;
window->priv->navigation_context = NULL;
+ window->priv->nav_alive = FALSE;
+ g_cond_signal (&window->priv->nav_destroy_cond);
+ g_mutex_unlock (&window->priv->nav_lock);
+
GST_INFO ("navigation loop exited\n");
return NULL;