ext/soup/gstsouphttpsrc.*: Fix seeking race condition in #540300
authorWouter Cloetens <wouter@mind.be>
Sat, 2 Aug 2008 21:39:01 +0000 (21:39 +0000)
committerJan Schmidt <thaytan@mad.scientist.com>
Sat, 2 Aug 2008 21:39:01 +0000 (21:39 +0000)
Original commit message from CVS:
* ext/soup/gstsouphttpsrc.c:
* ext/soup/gstsouphttpsrc.h:
Fix seeking race condition in #540300
Patch By: Wouter Cloetens  <wouter at mind be>

ChangeLog
ext/soup/gstsouphttpsrc.c
ext/soup/gstsouphttpsrc.h

index 0fae75e9af63fac04ac27ab6e5f7d07273d4b803..b15938c9a7890539a39aa8c52e400264745e7229 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-08-02  Jan Schmidt  <jan.schmidt@sun.com>
+
+       * ext/soup/gstsouphttpsrc.c:
+       * ext/soup/gstsouphttpsrc.h:
+       Fix seeking race condition in #540300
+       Patch By: Wouter Cloetens  <wouter at mind be>
+
 2008-08-02  Sebastian Dröge  <sebastian.droege@collabora.co.uk>
 
        * gst/matroska/matroska-demux.c: (gst_matroskademux_do_index_seek),
index 48360ab1e75eeb8de4c0808c5944e55a170de369..8ecde0d6c7c434ee0117506297b8c55d5dbdb84e 100644 (file)
@@ -495,8 +495,10 @@ gst_soup_http_src_unicodify (const gchar * str)
 static void
 gst_soup_http_src_cancel_message (GstSoupHTTPSrc * src)
 {
-  if (src->msg != NULL)
+  if (src->msg != NULL) {
+    src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_CANCELLED;
     soup_session_cancel_message (src->session, src->msg, SOUP_STATUS_CANCELLED);
+  }
   src->session_io_status = GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE;
   src->msg = NULL;
 }
@@ -695,19 +697,21 @@ gst_soup_http_src_finished_cb (SoupMessage * msg, GstSoupHTTPSrc * src)
   }
   GST_DEBUG_OBJECT (src, "finished");
   src->ret = GST_FLOW_UNEXPECTED;
-  if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING &&
-      src->read_position > 0) {
+  if (src->session_io_status == GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_CANCELLED) {
+    /* gst_soup_http_src_cancel_message() triggered this; probably a seek
+     * that occurred in the QUEUEING state; i.e. before the connection setup
+     * was complete. Do nothing */
+  } else if (src->session_io_status ==
+      GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING && src->read_position > 0) {
     /* The server disconnected while streaming. Reconnect and seeking to the
      * last location. */
     src->retry = TRUE;
     src->ret = GST_FLOW_CUSTOM_ERROR;
   } else if (G_UNLIKELY (src->session_io_status !=
           GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING)) {
-    if (msg->status_code != SOUP_STATUS_CANCELLED) {
-      GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
-          ("%s", msg->reason_phrase),
-          ("libsoup status code %d", msg->status_code));
-    }
+    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
+        ("%s", msg->reason_phrase),
+        ("libsoup status code %d", msg->status_code));
   }
   if (src->loop)
     g_main_loop_quit (src->loop);
@@ -850,6 +854,8 @@ gst_soup_http_src_response_cb (SoupSession * session, SoupMessage * msg,
     src->retry = TRUE;
   } else
     gst_soup_http_src_parse_status (msg, src);
+  /* The session's SoupMessage object expires after this callback returns. */
+  src->msg = NULL;
   g_main_loop_quit (src->loop);
 }
 
@@ -993,6 +999,9 @@ gst_soup_http_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
       case GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING:
         gst_soup_http_src_session_unpause_message (src);
         break;
+      case GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_CANCELLED:
+        /* Impossible. */
+        break;
     }
 
     if (src->ret == GST_FLOW_CUSTOM_ERROR)
index f959a4f19a50224629594733534100bdd5d51e6c..464da3400d3b30021cee77edbec5d0d46f4616cb 100644 (file)
@@ -42,6 +42,7 @@ typedef enum {
   GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_IDLE,
   GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_QUEUED,
   GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_RUNNING,
+  GST_SOUP_HTTP_SRC_SESSION_IO_STATUS_CANCELLED,
 } GstSoupHTTPSrcSessionIOStatus;
 
 struct _GstSoupHTTPSrc {