From 6a56e3080ddcf01dd10e33630fc0fd46e09a39f8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 8 Feb 2005 14:04:31 +0000 Subject: [PATCH] gst/gstthread.c: Implement state-change error handling (#166073). Original commit message from CVS: * gst/gstthread.c: (gst_thread_change_state): Implement state-change error handling (#166073). --- ChangeLog | 5 +++++ gst/gstthread.c | 29 +++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 46b076b..9d9a404 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2005-02-08 Ronald S. Bultje + * gst/gstthread.c: (gst_thread_change_state): + Implement state-change error handling (#166073). + +2005-02-08 Ronald S. Bultje + * gst/gstqueue.c: (gst_queue_chain), (gst_queue_get): Release interrupt after handling (#166250). diff --git a/gst/gstthread.c b/gst/gstthread.c index fe7849a..3e87ef9 100644 --- a/gst/gstthread.c +++ b/gst/gstthread.c @@ -419,7 +419,7 @@ gst_thread_change_state (GstElement * element) GstThread *thread; GstElementStateReturn ret; gint transition; - gboolean is_self; + gboolean is_self, reverting = FALSE; g_return_val_if_fail (GST_IS_THREAD (element), GST_STATE_FAILURE); @@ -432,7 +432,9 @@ gst_thread_change_state (GstElement * element) /* boolean to check if we called the state change in the same thread as * the iterate thread */ is_self = (thread == gst_thread_get_current ()); + transition = GST_STATE_TRANSITION (element); +revert: GST_LOG_OBJECT (thread, "grabbing lock"); g_mutex_lock (thread->lock); @@ -443,20 +445,22 @@ gst_thread_change_state (GstElement * element) /* do not try to grab the lock if this method is called from the * same thread as the iterate thread, the lock might be held and we * might deadlock */ - if (!is_self) + if (!is_self && !reverting) g_mutex_lock (thread->iterate_lock); - transition = GST_STATE_TRANSITION (element); - switch (transition) { - case GST_STATE_NULL_TO_READY: + case GST_STATE_NULL_TO_READY:{ + GError *err = NULL; + /* create the thread */ GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING); GST_LOG_OBJECT (element, "grabbing lock"); thread->thread_id = g_thread_create_full (gst_thread_main_loop, - thread, STACK_SIZE, FALSE, TRUE, thread->priority, NULL); + thread, STACK_SIZE, FALSE, TRUE, thread->priority, &err); if (!thread->thread_id) { - GST_ERROR_OBJECT (element, "g_thread_create_full failed"); + GST_ERROR_OBJECT (element, "g_thread_create_full failed: %s", + err->message); + g_error_free (err); goto error_out; } GST_LOG_OBJECT (element, "GThread created"); @@ -464,6 +468,7 @@ gst_thread_change_state (GstElement * element) /* wait for it to 'spin up' */ g_cond_wait (thread->cond, thread->lock); break; + } case GST_STATE_READY_TO_PAUSED: break; case GST_STATE_PAUSED_TO_PLAYING: @@ -529,8 +534,15 @@ gst_thread_change_state (GstElement * element) GST_LOG_OBJECT (thread, "unlocking lock"); g_mutex_unlock (thread->lock); - if (GST_ELEMENT_CLASS (parent_class)->change_state) { + if (reverting) { + goto error_out_unlocked; + } else if (GST_ELEMENT_CLASS (parent_class)->change_state) { ret = GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT (thread)); + if (ret == GST_STATE_FAILURE) { + reverting = TRUE; + transition = ((transition & 0xff) << 8) | (transition >> 8); + goto revert; + } } else { ret = GST_STATE_SUCCESS; } @@ -558,6 +570,7 @@ error_out: g_mutex_unlock (thread->lock); +error_out_unlocked: if (!is_self) g_mutex_unlock (thread->iterate_lock); -- 2.7.4