gst/gstthread.c: Implement state-change error handling (#166073).
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Tue, 8 Feb 2005 14:04:31 +0000 (14:04 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Tue, 8 Feb 2005 14:04:31 +0000 (14:04 +0000)
Original commit message from CVS:
* gst/gstthread.c: (gst_thread_change_state):
Implement state-change error handling (#166073).

ChangeLog
gst/gstthread.c

index 46b076b..9d9a404 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 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>
+
        * gst/gstqueue.c: (gst_queue_chain), (gst_queue_get):
          Release interrupt after handling (#166250).
 
index fe7849a..3e87ef9 100644 (file)
@@ -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);