check/gst/gstbin.c: add more things to check
authorThomas Vander Stichele <thomas@apestaart.org>
Sat, 9 Jul 2005 22:54:28 +0000 (22:54 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Sat, 9 Jul 2005 22:54:28 +0000 (22:54 +0000)
Original commit message from CVS:

* check/gst/gstbin.c: (pop_messages), (GST_START_TEST),
(gst_bin_suite):
add more things to check
* gst/gstbin.c: (gst_bin_change_state), (bin_bus_handler):
* gst/gstelement.c:
more debug

ChangeLog
check/gst/gstbin.c
gst/gstbin.c
gst/gstelement.c
tests/check/gst/gstbin.c

index a5c71be..8e9b7c2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2005-07-09  Thomas Vander Stichele  <thomas at apestaart dot org>
 
+       * check/gst/gstbin.c: (pop_messages), (GST_START_TEST),
+       (gst_bin_suite):
+         add more things to check
+       * gst/gstbin.c: (gst_bin_change_state), (bin_bus_handler):
+       * gst/gstelement.c:
+         more debug
+
+2005-07-09  Thomas Vander Stichele  <thomas at apestaart dot org>
+
        * check/elements/gstfakesrc.c: (chain_func), (event_func),
        (GST_START_TEST), (fakesrc_suite):
        * check/gst-libs/gdp.c: (GST_START_TEST):
index ae29928..d6c87a1 100644 (file)
 
 #include "../gstcheck.h"
 
+static void
+pop_messages (GstBus * bus, int count)
+{
+  GstMessage *message;
+
+  int i;
+
+  GST_DEBUG ("popping %d messages", count);
+  for (i = 0; i < count; ++i) {
+    fail_unless (gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1)
+        == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
+
+    message = gst_bus_pop (bus);
+    gst_message_unref (message);
+  }
+  GST_DEBUG ("popped %d messages", count);
+}
+
 GST_START_TEST (test_interface)
 {
   GstBin *bin, *bin2;
@@ -137,11 +155,12 @@ GST_START_TEST (test_message_state_changed_child)
 
   bus = GST_ELEMENT_BUS (bin);
 
-  /* change state, spawning three messages:
-   * - first for fakesrc, causing incref on fakesrc
-   * - then two on bin, causing an incref on the bin */
+  /* change state, spawning two messages:
+   * - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
+   * - second for bin, causing an incref on the bin */
   GST_DEBUG ("setting bin to READY");
-  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
+  fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY)
+      == GST_STATE_SUCCESS);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 2);
   ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
@@ -151,6 +170,7 @@ GST_START_TEST (test_message_state_changed_child)
       == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
 
   message = gst_bus_pop (bus);
+  fail_unless (message->src == GST_OBJECT (src));
   gst_message_unref (message);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
@@ -161,6 +181,7 @@ GST_START_TEST (test_message_state_changed_child)
       == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
 
   message = gst_bus_pop (bus);
+  fail_unless (message->src == GST_OBJECT (bin));
   gst_message_unref (message);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
@@ -172,6 +193,72 @@ GST_START_TEST (test_message_state_changed_child)
 
 GST_END_TEST;
 
+GST_START_TEST (test_message_state_changed_children)
+{
+  GstPipeline *pipeline;
+  GstElement *src, *sink;
+  GstBus *bus;
+
+  pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
+  fail_unless (pipeline != NULL, "Could not create pipeline");
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  src = gst_element_factory_make ("fakesrc", NULL);
+  fail_if (src == NULL, "Could not create fakesrc");
+  gst_bin_add (GST_BIN (pipeline), src);
+
+  sink = gst_element_factory_make ("fakesink", NULL);
+  fail_if (sink == NULL, "Could not create fakesink");
+  gst_bin_add (GST_BIN (pipeline), sink);
+
+  fail_unless (gst_element_link (src, sink), "could not link src and sink");
+
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "sink", 1);
+
+  bus = GST_ELEMENT_BUS (pipeline);
+
+  /* change state, spawning three times three messages */
+  GST_DEBUG ("setting pipeline to PLAYING");
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING)
+      == GST_STATE_SUCCESS);
+
+  pop_messages (bus, 9);
+
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* go back to READY, spawning six messages */
+  GST_DEBUG ("setting pipeline to READY");
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
+      == GST_STATE_SUCCESS);
+
+  /* each object is referenced by two messages */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 3);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
+
+  pop_messages (bus, 6);
+
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* setting pipeline to NULL flushes the bus automatically */
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL)
+      == GST_STATE_SUCCESS);
+
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* clean up */
+  gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
 
 Suite *
 gst_bin_suite (void)
@@ -183,6 +270,7 @@ gst_bin_suite (void)
   tcase_add_test (tc_chain, test_interface);
   tcase_add_test (tc_chain, test_message_state_changed);
   tcase_add_test (tc_chain, test_message_state_changed_child);
+  tcase_add_test (tc_chain, test_message_state_changed_children);
 
   return s;
 }
index 6ade4a2..c8d840c 100644 (file)
@@ -1190,8 +1190,12 @@ restart:
     }
 
     GST_LOCK (bin);
-    if (G_UNLIKELY (children_cookie != bin->children_cookie))
+    if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
+      /* FIXME: we reffed some children already, are we leaking refcounts
+       * in that case ? */
+      GST_INFO_OBJECT (bin, "bin->children_cookie changed, restarting");
       goto restart;
+    }
     children = g_list_next (children);
   }
   GST_UNLOCK (bin);
@@ -1445,12 +1449,14 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
 static GstBusSyncReply
 bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
 {
+  GST_DEBUG_OBJECT (bin, "[msg %p] handling child message of type %d from %s",
+      message, GST_MESSAGE_TYPE (message),
+      gst_object_get_name (GST_MESSAGE_SRC (message)));
   /* we don't want messages from the streaming thread while we're doing the
    * state change. We do want them from the state change functions. */
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_EOS:
-      GST_DEBUG_OBJECT (bin, "got EOS message from %s",
-          gst_object_get_name (GST_MESSAGE_SRC (message)));
+      GST_DEBUG_OBJECT (bin, "got EOS message");
 
       GST_LOCK (bin->child_bus);
       bin->eosed = g_list_prepend (bin->eosed, GST_MESSAGE_SRC (message));
@@ -1467,6 +1473,7 @@ bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
       break;
     default:
       /* Send all other messages upward */
+      GST_DEBUG_OBJECT (bin, "posting message upward");
       gst_bus_post (GST_ELEMENT (bin)->bus, message);
       break;
   }
index 8fde607..ec8b6c9 100644 (file)
@@ -1231,7 +1231,7 @@ gst_element_query (GstElement * element, GstQuery * query)
  * @element: a #GstElement posting the message
  * @message: a #GstMessage to post
  *
- * Post a message on the elements #GstBus.
+ * Post a message on the element's #GstBus.
  *
  * Returns: TRUE if the message was successfully posted.
  *
index ae29928..d6c87a1 100644 (file)
 
 #include "../gstcheck.h"
 
+static void
+pop_messages (GstBus * bus, int count)
+{
+  GstMessage *message;
+
+  int i;
+
+  GST_DEBUG ("popping %d messages", count);
+  for (i = 0; i < count; ++i) {
+    fail_unless (gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1)
+        == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
+
+    message = gst_bus_pop (bus);
+    gst_message_unref (message);
+  }
+  GST_DEBUG ("popped %d messages", count);
+}
+
 GST_START_TEST (test_interface)
 {
   GstBin *bin, *bin2;
@@ -137,11 +155,12 @@ GST_START_TEST (test_message_state_changed_child)
 
   bus = GST_ELEMENT_BUS (bin);
 
-  /* change state, spawning three messages:
-   * - first for fakesrc, causing incref on fakesrc
-   * - then two on bin, causing an incref on the bin */
+  /* change state, spawning two messages:
+   * - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
+   * - second for bin, causing an incref on the bin */
   GST_DEBUG ("setting bin to READY");
-  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
+  fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY)
+      == GST_STATE_SUCCESS);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 2);
   ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
@@ -151,6 +170,7 @@ GST_START_TEST (test_message_state_changed_child)
       == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
 
   message = gst_bus_pop (bus);
+  fail_unless (message->src == GST_OBJECT (src));
   gst_message_unref (message);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
@@ -161,6 +181,7 @@ GST_START_TEST (test_message_state_changed_child)
       == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
 
   message = gst_bus_pop (bus);
+  fail_unless (message->src == GST_OBJECT (bin));
   gst_message_unref (message);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
@@ -172,6 +193,72 @@ GST_START_TEST (test_message_state_changed_child)
 
 GST_END_TEST;
 
+GST_START_TEST (test_message_state_changed_children)
+{
+  GstPipeline *pipeline;
+  GstElement *src, *sink;
+  GstBus *bus;
+
+  pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
+  fail_unless (pipeline != NULL, "Could not create pipeline");
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  src = gst_element_factory_make ("fakesrc", NULL);
+  fail_if (src == NULL, "Could not create fakesrc");
+  gst_bin_add (GST_BIN (pipeline), src);
+
+  sink = gst_element_factory_make ("fakesink", NULL);
+  fail_if (sink == NULL, "Could not create fakesink");
+  gst_bin_add (GST_BIN (pipeline), sink);
+
+  fail_unless (gst_element_link (src, sink), "could not link src and sink");
+
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "sink", 1);
+
+  bus = GST_ELEMENT_BUS (pipeline);
+
+  /* change state, spawning three times three messages */
+  GST_DEBUG ("setting pipeline to PLAYING");
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING)
+      == GST_STATE_SUCCESS);
+
+  pop_messages (bus, 9);
+
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* go back to READY, spawning six messages */
+  GST_DEBUG ("setting pipeline to READY");
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
+      == GST_STATE_SUCCESS);
+
+  /* each object is referenced by two messages */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 3);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
+
+  pop_messages (bus, 6);
+
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* setting pipeline to NULL flushes the bus automatically */
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL)
+      == GST_STATE_SUCCESS);
+
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* clean up */
+  gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
 
 Suite *
 gst_bin_suite (void)
@@ -183,6 +270,7 @@ gst_bin_suite (void)
   tcase_add_test (tc_chain, test_interface);
   tcase_add_test (tc_chain, test_message_state_changed);
   tcase_add_test (tc_chain, test_message_state_changed_child);
+  tcase_add_test (tc_chain, test_message_state_changed_children);
 
   return s;
 }