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).
This commit is contained in:
Ronald S. Bultje 2005-02-08 14:04:31 +00:00
parent eb3c38de8c
commit 6a56e3080d
2 changed files with 26 additions and 8 deletions

View file

@ -1,3 +1,8 @@
2005-02-08 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/gstthread.c: (gst_thread_change_state):
Implement state-change error handling (#166073).
2005-02-08 Ronald S. Bultje <rbultje@ronald.bitfreak.net> 2005-02-08 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* gst/gstqueue.c: (gst_queue_chain), (gst_queue_get): * gst/gstqueue.c: (gst_queue_chain), (gst_queue_get):

View file

@ -419,7 +419,7 @@ gst_thread_change_state (GstElement * element)
GstThread *thread; GstThread *thread;
GstElementStateReturn ret; GstElementStateReturn ret;
gint transition; gint transition;
gboolean is_self; gboolean is_self, reverting = FALSE;
g_return_val_if_fail (GST_IS_THREAD (element), GST_STATE_FAILURE); 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 /* boolean to check if we called the state change in the same thread as
* the iterate thread */ * the iterate thread */
is_self = (thread == gst_thread_get_current ()); is_self = (thread == gst_thread_get_current ());
transition = GST_STATE_TRANSITION (element);
revert:
GST_LOG_OBJECT (thread, "grabbing lock"); GST_LOG_OBJECT (thread, "grabbing lock");
g_mutex_lock (thread->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 /* 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 * same thread as the iterate thread, the lock might be held and we
* might deadlock */ * might deadlock */
if (!is_self) if (!is_self && !reverting)
g_mutex_lock (thread->iterate_lock); g_mutex_lock (thread->iterate_lock);
transition = GST_STATE_TRANSITION (element);
switch (transition) { switch (transition) {
case GST_STATE_NULL_TO_READY: case GST_STATE_NULL_TO_READY:{
GError *err = NULL;
/* create the thread */ /* create the thread */
GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING); GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING);
GST_LOG_OBJECT (element, "grabbing lock"); GST_LOG_OBJECT (element, "grabbing lock");
thread->thread_id = g_thread_create_full (gst_thread_main_loop, 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) { 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; goto error_out;
} }
GST_LOG_OBJECT (element, "GThread created"); GST_LOG_OBJECT (element, "GThread created");
@ -464,6 +468,7 @@ gst_thread_change_state (GstElement * element)
/* wait for it to 'spin up' */ /* wait for it to 'spin up' */
g_cond_wait (thread->cond, thread->lock); g_cond_wait (thread->cond, thread->lock);
break; break;
}
case GST_STATE_READY_TO_PAUSED: case GST_STATE_READY_TO_PAUSED:
break; break;
case GST_STATE_PAUSED_TO_PLAYING: case GST_STATE_PAUSED_TO_PLAYING:
@ -529,8 +534,15 @@ gst_thread_change_state (GstElement * element)
GST_LOG_OBJECT (thread, "unlocking lock"); GST_LOG_OBJECT (thread, "unlocking lock");
g_mutex_unlock (thread->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)); 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 { } else {
ret = GST_STATE_SUCCESS; ret = GST_STATE_SUCCESS;
} }
@ -558,6 +570,7 @@ error_out:
g_mutex_unlock (thread->lock); g_mutex_unlock (thread->lock);
error_out_unlocked:
if (!is_self) if (!is_self)
g_mutex_unlock (thread->iterate_lock); g_mutex_unlock (thread->iterate_lock);