Fix extended message handling with gst_bus_pop_timed_filtered()
authorJan Schmidt <jan@centricular.com>
Sun, 16 Mar 2014 19:29:27 +0000 (06:29 +1100)
committerJan Schmidt <jan@centricular.com>
Sun, 16 Mar 2014 19:29:27 +0000 (06:29 +1100)
Make sure extended message types don't get accidentally matched
when not asked for in the mask

gst/gstbus.c
gst/gstmessage.h
tests/check/gst/gstbus.c

index 7e584f8..185751c 100644 (file)
@@ -505,13 +505,18 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout,
           message, GST_MESSAGE_TYPE_NAME (message),
           GST_MESSAGE_SRC_NAME (message), (guint) types);
       if ((GST_MESSAGE_TYPE (message) & types) != 0) {
-        /* exit the loop, we have a message */
-        goto beach;
-      } else {
-        GST_DEBUG_OBJECT (bus, "discarding message, does not match mask");
-        gst_message_unref (message);
-        message = NULL;
+        /* Extra check to ensure extended types don't get matched unless
+         * asked for */
+        if ((GST_MESSAGE_TYPE_IS_EXTENDED (message) == FALSE)
+            || (types & GST_MESSAGE_EXTENDED)) {
+          /* exit the loop, we have a message */
+          goto beach;
+        }
       }
+
+      GST_DEBUG_OBJECT (bus, "discarding message, does not match mask");
+      gst_message_unref (message);
+      message = NULL;
     }
 
     /* no need to wait, exit loop */
index 28a347b..c9da762 100644 (file)
@@ -188,6 +188,15 @@ typedef enum
  */
 #define GST_MESSAGE_TYPE(message)       (GST_MESSAGE_CAST(message)->type)
 /**
+ * GST_MESSAGE_TYPE_IS_EXTENDED:
+ * @message: a #GstMessage
+ *
+ * Check if the message is in the extended message group
+ * (Since 1.4)
+ */
+#define GST_MESSAGE_TYPE_IS_EXTENDED(message)       (!!(GST_MESSAGE_CAST(message)->type & GST_MESSAGE_EXTENDED))
+
+/**
  * GST_MESSAGE_TYPE_NAME:
  * @message: a #GstMessage
  *
index 6168d24..5eaa7f1 100644 (file)
@@ -23,6 +23,8 @@
 static GstBus *test_bus = NULL;
 static GMainLoop *main_loop;
 
+static GType foo_device_get_type (void);
+
 #define NUM_MESSAGES 1000
 #define NUM_THREADS 10
 
@@ -295,7 +297,7 @@ message_func (GstBus * bus, GstMessage * message, gpointer data)
 }
 
 static void
-send_5app_1el_1err_2app_messages (guint interval_usecs)
+send_5app_1el_1err_2app_1eos_messages (guint interval_usecs)
 {
   GstMessage *m;
   GstStructure *s;
@@ -328,8 +330,36 @@ send_5app_1el_1err_2app_messages (guint interval_usecs)
     gst_bus_post (test_bus, m);
     g_usleep (interval_usecs);
   }
+  for (i = 0; i < 1; i++) {
+    m = gst_message_new_eos (NULL);
+    GST_LOG ("posting EOS message");
+    gst_bus_post (test_bus, m);
+    g_usleep (interval_usecs);
+  }
+}
+
+static void
+send_extended_messages (guint interval_usecs)
+{
+  GstMessage *msg;
+  GstDevice *device;
+
+  device = g_object_new (foo_device_get_type (), NULL);
+
+  msg = gst_message_new_device_added (NULL, device);
+  GST_LOG ("posting device-added message");
+  gst_bus_post (test_bus, msg);
+  g_usleep (interval_usecs);
+
+  msg = gst_message_new_device_removed (NULL, device);
+  GST_LOG ("posting device-removed message");
+  gst_bus_post (test_bus, msg);
+  g_usleep (interval_usecs);
+
+  gst_object_unref (device);
 }
 
+
 static void
 send_10_app_messages (void)
 {
@@ -390,8 +420,6 @@ GST_START_TEST (test_timed_pop)
 
 GST_END_TEST;
 
-static GType foo_device_get_type (void);
-
 typedef struct
 {
   GstDevice device;
@@ -444,7 +472,7 @@ GST_START_TEST (test_timed_pop_filtered)
   msg = gst_bus_timed_pop_filtered (test_bus, 0, GST_MESSAGE_ANY);
   fail_unless (msg == NULL);
 
-  send_5app_1el_1err_2app_messages (0);
+  send_5app_1el_1err_2app_1eos_messages (0);
   msg = gst_bus_timed_pop_filtered (test_bus, 0,
       GST_MESSAGE_ANY ^ GST_MESSAGE_APPLICATION);
   fail_unless (msg != NULL);
@@ -458,23 +486,45 @@ GST_START_TEST (test_timed_pop_filtered)
   msg = gst_bus_timed_pop_filtered (test_bus, 0, GST_MESSAGE_ERROR);
   fail_unless (msg == NULL);
 
-  send_5app_1el_1err_2app_messages (0);
-  {
-    GstDevice *device;
+  gst_object_unref (test_bus);
 
-    device = g_object_new (foo_device_get_type (), NULL);
-    msg = gst_message_new_device_added (NULL, device);
-    gst_object_unref (device);
+  /* Test extended messages */
+  GST_DEBUG
+      ("Checking extended messages received from gst_bus_timed_pop_filtered");
+  test_bus = gst_bus_new ();
 
-    GST_LOG ("posting device message");
-    gst_bus_post (test_bus, msg);
-  }
-  send_5app_1el_1err_2app_messages (0);
+  send_5app_1el_1err_2app_1eos_messages (0);
+  send_extended_messages (0);
+  send_5app_1el_1err_2app_1eos_messages (0);
   msg = gst_bus_timed_pop_filtered (test_bus, 0, GST_MESSAGE_EXTENDED);
   fail_unless (msg != NULL);
   fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_DEVICE_ADDED);
   gst_message_unref (msg);
 
+  msg = gst_bus_timed_pop_filtered (test_bus, 0, GST_MESSAGE_EXTENDED);
+  fail_unless (msg != NULL);
+  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_DEVICE_REMOVED);
+  gst_message_unref (msg);
+  gst_object_unref (test_bus);
+
+  /* Now check extended messages don't appear when we don't ask for them */
+  GST_DEBUG
+      ("Checking extended messages *not* received from gst_bus_timed_pop_filtered when not wanted");
+  test_bus = gst_bus_new ();
+
+  send_extended_messages (0);
+  send_5app_1el_1err_2app_1eos_messages (0);
+
+  msg = gst_bus_timed_pop_filtered (test_bus, 0, GST_MESSAGE_ERROR);
+  fail_unless (msg != NULL);
+  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_ERROR);
+  gst_message_unref (msg);
+
+  msg = gst_bus_timed_pop_filtered (test_bus, 0, GST_MESSAGE_EOS);
+  fail_unless (msg != NULL);
+  fail_unless_equals_int (GST_MESSAGE_TYPE (msg), GST_MESSAGE_EOS);
+  gst_message_unref (msg);
+
   gst_object_unref (test_bus);
 }
 
@@ -484,7 +534,7 @@ static gpointer
 post_delayed_thread (gpointer data)
 {
   THREAD_START ();
-  send_5app_1el_1err_2app_messages (1 * G_USEC_PER_SEC);
+  send_5app_1el_1err_2app_1eos_messages (1 * G_USEC_PER_SEC);
   return NULL;
 }