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 ()
This commit is contained in:
Matthew Waters 2016-10-05 18:32:09 +11:00 committed by Tim-Philipp Müller
parent c0cb6eacb5
commit 126ee924c0

View file

@ -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;