bus: Make sure to always read the control after popping a message
authorSebastian Dröge <sebastian@centricular.com>
Wed, 29 Jun 2016 12:02:55 +0000 (14:02 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 29 Jun 2016 19:21:04 +0000 (21:21 +0200)
It might happen that we popped the message before writing of the control
happened. In this case we just have to retry again a bit later, and failure to
do so will cause an additional byte in the control and the GSource /
gst_poll_wait() to always wake up again immediately.

https://bugzilla.gnome.org/show_bug.cgi?id=750397

gst/gstbus.c

index b8c2995..a443f41 100644 (file)
@@ -515,8 +515,24 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout,
         gst_atomic_queue_length (bus->priv->queue));
 
     while ((message = gst_atomic_queue_pop (bus->priv->queue))) {
-      if (bus->priv->poll)
-        gst_poll_read_control (bus->priv->poll);
+      if (bus->priv->poll) {
+        while (!gst_poll_read_control (bus->priv->poll)) {
+          if (errno == EWOULDBLOCK) {
+            /* Retry, this can happen if pushing to the queue has finished,
+             * popping here succeeded but writing control did not finish
+             * before we got to this line. */
+            /* Give other threads the chance to do something */
+            g_thread_yield ();
+            continue;
+          } else {
+            /* This is a real error and means that either the bus is in an
+             * inconsistent state, or the GstPoll is invalid. GstPoll already
+             * prints a critical warning about this, no need to do that again
+             * ourselves */
+            break;
+          }
+        }
+      }
 
       GST_DEBUG_OBJECT (bus, "got message %p, %s from %s, type mask is %u",
           message, GST_MESSAGE_TYPE_NAME (message),