mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
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:
parent
eb3c38de8c
commit
6a56e3080d
2 changed files with 26 additions and 8 deletions
|
@ -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):
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue