check/Makefile.am: clean up environment for when registry gets built versus when...
authorThomas Vander Stichele <thomas@apestaart.org>
Sun, 21 Aug 2005 15:01:18 +0000 (15:01 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Sun, 21 Aug 2005 15:01:18 +0000 (15:01 +0000)
Original commit message from CVS:

* check/Makefile.am:
clean up environment for when registry gets built versus
when actual tests are run; valgrind seems to not report
leaks if GST_PLUGIN_PATH is set to some specific values
* check/gst/gstbin.c: (GST_START_TEST):
add more refcounting checks; maybe this exposes a
preroll lock bug ?
* common/check.mak:
* gst/base/gstbasesink.c: (gst_base_sink_handle_object):
* gst/check/gstcheck.h:
* gst/gstbin.c: (bin_element_is_semi_sink), (gst_bin_get_state),
(gst_bin_change_state):
* gst/gstpad.c: (gst_pad_activate_push), (gst_pad_chain):
add/fix debugging/whitespace

12 files changed:
ChangeLog
check/Makefile.am
check/gst/gstbin.c
common
gst/base/gstbasesink.c
gst/check/gstcheck.h
gst/gstbin.c
gst/gstpad.c
libs/gst/base/gstbasesink.c
libs/gst/check/gstcheck.h
tests/check/Makefile.am
tests/check/gst/gstbin.c

index 9039d28..35bd4c7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-08-21  Thomas Vander Stichele  <thomas at apestaart dot org>
+
+       * check/Makefile.am:
+         clean up environment for when registry gets built versus
+         when actual tests are run; valgrind seems to not report
+         leaks if GST_PLUGIN_PATH is set to some specific values
+       * check/gst/gstbin.c: (GST_START_TEST):
+         add more refcounting checks; maybe this exposes a
+         preroll lock bug ?
+       * common/check.mak:
+       * gst/base/gstbasesink.c: (gst_base_sink_handle_object):
+       * gst/check/gstcheck.h:
+       * gst/gstbin.c: (bin_element_is_semi_sink), (gst_bin_get_state),
+       (gst_bin_change_state):
+       * gst/gstpad.c: (gst_pad_activate_push), (gst_pad_chain):
+         add/fix debugging/whitespace
+
 2005-08-21  Jan Schmidt  <thaytan@mad.scientist.com>
 
        * check/gst/gstevent.c: (event_probe), (test_event),
index a293e8d..655d9f0 100644 (file)
@@ -4,9 +4,14 @@ CHECK_REGISTRY = $(top_builddir)/check/test-registry.xml
 
 GST_TOOLS_DIR = $(top_builddir)/tools
 
-TESTS_ENVIRONMENT=\
+REGISTRY_ENVIRONMENT = \
        GST_REGISTRY=$(CHECK_REGISTRY)
 
+TESTS_ENVIRONMENT = \
+        $(REGISTRY_ENVIRONMENT)                                 \
+        GST_PLUGIN_PATH_ONLY=yes                                \
+        GST_PLUGIN_PATH=$(top_builddir)/gst
+
 plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
 
 # rebuild gst-register-@GST_MAJORMINOR@ if needed
@@ -25,13 +30,9 @@ clean-local: clean-local-check
 
 $(CHECK_REGISTRY):
        $(TESTS_ENVIRONMENT)                                    \
-       GST_PLUGIN_PATH_ONLY=yes                                \
-       GST_PLUGIN_PATH=$(top_builddir)/gst                     \
-       $(top_builddir)/tools/gst-register
+       $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@
 
-# FIXME: it'd be nicer to run the versioned register, but in that case
-# "make dist" complains about not finding gst-register-0.9.c
-TESTS = $(top_builddir)/tools/gst-register     \
+check_PROGRAMS =                               \
        gst/gst                                 \
        gst/gstbin                              \
         gst/gstbuffer                          \
@@ -57,7 +58,8 @@ TESTS = $(top_builddir)/tools/gst-register    \
        gst-libs/controller                     \
        gst-libs/gdp
 
-check_PROGRAMS = $(TESTS)
+TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@    \
+       $(check_PROGRAMS)
 
 noinst_HEADERS = gst/capslist.h
 
@@ -89,7 +91,7 @@ TESTS_THREADED =                              \
        gst/gstminiobject                       \
        gst/gstobject
 
-VALGRIND_TESTS_DISABLE =                       \
-       $(top_builddir)/tools/gst-register      \
-       $(TESTS_THREADED)                       \
+VALGRIND_TESTS_DISABLE =                                       \
+       $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@     \
+       $(TESTS_THREADED)                                       \
        $(TESTS_TO_FIX)
index 61ae0d2..8394950 100644 (file)
@@ -221,26 +221,72 @@ GST_START_TEST (test_message_state_changed_children)
 
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
-  ASSERT_OBJECT_REFCOUNT (src, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
 
   bus = GST_ELEMENT_BUS (pipeline);
 
-  /* change state, spawning three times three messages */
+  /* change state to READY, spawning three 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 a message */
+  ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+  pop_messages (bus, 3);
+  fail_if ((gst_bus_pop (bus)) != NULL);
+
+  ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* change state to PAUSED, spawning three messages */
+  GST_DEBUG ("setting pipeline to PAUSED");
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
+      == GST_STATE_SUCCESS);
+
+  /* each object is referenced by a message;
+   * base_sink_chain has taken a refcount on the sink, and is blocked on
+   * preroll */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+  pop_messages (bus, 3);
+  fail_if ((gst_bus_pop (bus)) != NULL);
+
+  ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* change state to PLAYING, spawning 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);
+  /* each object is referenced by one message; sink still has an extra
+   * because it's still blocked on preroll */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+  pop_messages (bus, 3);
+  fail_if ((gst_bus_pop (bus)) != NULL);
 
-  /* this test is completely bogus as the refcount can change while running */
-#if 0
   ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
-  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
-#endif
 
   /* go back to READY, spawning six messages */
+  /* FIXME: only now does the sink get unblocked from preroll
+   * (check log for "done preroll")
+   * mabe that's a bug ? */
   GST_DEBUG ("setting pipeline to READY");
   fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
       == GST_STATE_SUCCESS);
@@ -251,6 +297,7 @@ GST_START_TEST (test_message_state_changed_children)
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
 
   pop_messages (bus, 6);
+  fail_if ((gst_bus_pop (bus)) != NULL);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
diff --git a/common b/common
index 609c771..aa2a757 160000 (submodule)
--- a/common
+++ b/common
@@ -1 +1 @@
-Subproject commit 609c7716bab17e1dc086d3b54b51740300ec6f0f
+Subproject commit aa2a757c587d91069a230d8e656481c3c364ccc6
index 23b6a22..0c469f7 100644 (file)
@@ -1,7 +1,7 @@
 /* GStreamer
  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
  *
- * gstbasesink.c: 
+ * gstbasesink.c:
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -473,7 +473,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
 
   GST_PREROLL_LOCK (pad);
   /* push object on the queue */
-  GST_DEBUG ("push on queue %p", basesink, obj);
+  GST_DEBUG_OBJECT (basesink, "push %p on preroll_queue", obj);
   g_queue_push_tail (basesink->preroll_queue, obj);
 
   have_event = GST_IS_EVENT (obj);
@@ -572,7 +572,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
 
     /* now we commit our state */
     GST_STATE_LOCK (basesink);
-    GST_DEBUG ("commit state %p >", basesink);
+    GST_DEBUG_OBJECT (basesink, "commit state");
     gst_element_commit_state (GST_ELEMENT (basesink));
     GST_STATE_UNLOCK (basesink);
 
@@ -604,10 +604,10 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
    * application thread and we don't want to block there. */
   if (length > basesink->preroll_queue_max_len && !have_event) {
     /* block until the state changes, or we get a flush, or something */
-    GST_DEBUG ("element %s waiting to finish preroll",
+    GST_DEBUG_OBJECT (basesink, "waiting to finish preroll",
         GST_ELEMENT_NAME (basesink));
     GST_PREROLL_WAIT (pad);
-    GST_DEBUG ("done preroll");
+    GST_DEBUG_OBJECT (basesink, "done preroll");
   }
   GST_LOCK (pad);
   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
@@ -651,7 +651,7 @@ playing_async:
       g_warning ("STREAM_LOCK should have been locked !!");
     }
     GST_STATE_LOCK (basesink);
-    GST_DEBUG ("commit state %p >", basesink);
+    GST_DEBUG_OBJECT (basesink, "commit state");
     gst_element_commit_state (GST_ELEMENT (basesink));
     GST_STATE_UNLOCK (basesink);
     if (t > 0)
@@ -686,7 +686,7 @@ preroll_failed:
 
     /* now we abort our state */
     GST_STATE_LOCK (basesink);
-    GST_DEBUG ("abort state %p >", basesink);
+    GST_DEBUG_OBJECT (basesink, "abort state");
     gst_element_abort_state (GST_ELEMENT (basesink));
     GST_STATE_UNLOCK (basesink);
 
@@ -983,7 +983,7 @@ gst_base_sink_chain (GstPad * pad, GstBuffer * buf)
   return result;
 }
 
-/* FIXME, not all sinks can operate in pull mode 
+/* FIXME, not all sinks can operate in pull mode
  */
 static void
 gst_base_sink_loop (GstPad * pad)
index 0627a48..556520f 100644 (file)
@@ -203,7 +203,8 @@ G_STMT_START {                                                      \
   int rc;                                                      \
   rc = GST_OBJECT_REFCOUNT_VALUE (object);                     \
   fail_unless (rc == value,                                    \
-      "%s refcount is %d instead of %d", name, rc, value);     \
+      "%s (%p) refcount is %d instead of %d",                  \
+      name, object, rc, value);                                        \
 } G_STMT_END
 
 #define ASSERT_CAPS_REFCOUNT(caps, name, value)                        \
index 4119fb1..3d6fe2c 100644 (file)
@@ -778,6 +778,7 @@ bin_element_is_semi_sink (GstElement * child, GstBin * bin)
     for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
       GstPad *peer;
 
+      GST_DEBUG ("looking at pad %p", pads->data);
       if ((peer = gst_pad_get_peer (GST_PAD_CAST (pads->data)))) {
         connected_src =
             has_ancestor (GST_OBJECT_CAST (peer), GST_OBJECT_CAST (bin));
@@ -892,7 +893,7 @@ restart:
       GstElement *child = GST_ELEMENT_CAST (children->data);
 
       gst_object_ref (child);
-      /* now we release the lock to enter a non blocking wait. We 
+      /* now we release the lock to enter a non blocking wait. We
        * release the lock anyway since we can. */
       GST_UNLOCK (bin);
 
@@ -1152,7 +1153,7 @@ restart:
   /* take base time */
   base_time = element->base_time;
 
-  /* make sure queues are empty, they could be filled when 
+  /* make sure queues are empty, they could be filled when
    * restarting. */
   clear_queue (elem_queue, TRUE);
   clear_queue (semi_queue, TRUE);
@@ -1160,6 +1161,7 @@ restart:
 
   children = bin->children;
   children_cookie = bin->children_cookie;
+  GST_DEBUG_OBJECT (bin, "reffing and examining children");
   while (children) {
     GstElement *child = GST_ELEMENT_CAST (children->data);
 
@@ -1183,7 +1185,9 @@ restart:
     }
     children = g_list_next (children);
   }
+  GST_DEBUG_OBJECT (bin, "reffed and examined children");
   GST_UNLOCK (bin);
+
   /* after this point new elements can be added/removed from the
    * bin. We operate on the snapshot taken above. Applications
    * should serialize their add/remove and set_state. */
@@ -1203,6 +1207,7 @@ restart:
   }
 
   /* second step, change state of elements in the queue */
+  GST_DEBUG_OBJECT (bin, "change state of elements in the queue");
   while (!g_queue_is_empty (elem_queue)) {
     GstElement *qelement;
     GList *pads;
index 9a60433..a6581a1 100644 (file)
@@ -634,6 +634,8 @@ gst_pad_activate_push (GstPad * pad, gboolean active)
   GstActivateMode old;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "trying to set %s in push mode",
+      active ? "activated" : "deactivated");
 
   GST_LOCK (pad);
   old = GST_PAD_ACTIVATE_MODE (pad);
@@ -2928,7 +2930,7 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
       goto not_negotiated;
   }
 
-  /* NOTE: we read the chainfunc unlocked. 
+  /* NOTE: we read the chainfunc unlocked.
    * we cannot hold the lock for the pad so we might send
    * the data to the wrong function. This is not really a
    * problem since functions are assigned at creation time
@@ -2942,6 +2944,10 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
 
   ret = chainfunc (pad, buffer);
 
+  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+      "called chainfunction &%s of pad %s:%s, returned %d",
+      GST_DEBUG_FUNCPTR_NAME (chainfunc), GST_DEBUG_PAD_NAME (pad), ret);
+
   GST_STREAM_UNLOCK (pad);
 
   return ret;
index 23b6a22..0c469f7 100644 (file)
@@ -1,7 +1,7 @@
 /* GStreamer
  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
  *
- * gstbasesink.c: 
+ * gstbasesink.c:
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -473,7 +473,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
 
   GST_PREROLL_LOCK (pad);
   /* push object on the queue */
-  GST_DEBUG ("push on queue %p", basesink, obj);
+  GST_DEBUG_OBJECT (basesink, "push %p on preroll_queue", obj);
   g_queue_push_tail (basesink->preroll_queue, obj);
 
   have_event = GST_IS_EVENT (obj);
@@ -572,7 +572,7 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
 
     /* now we commit our state */
     GST_STATE_LOCK (basesink);
-    GST_DEBUG ("commit state %p >", basesink);
+    GST_DEBUG_OBJECT (basesink, "commit state");
     gst_element_commit_state (GST_ELEMENT (basesink));
     GST_STATE_UNLOCK (basesink);
 
@@ -604,10 +604,10 @@ gst_base_sink_handle_object (GstBaseSink * basesink, GstPad * pad,
    * application thread and we don't want to block there. */
   if (length > basesink->preroll_queue_max_len && !have_event) {
     /* block until the state changes, or we get a flush, or something */
-    GST_DEBUG ("element %s waiting to finish preroll",
+    GST_DEBUG_OBJECT (basesink, "waiting to finish preroll",
         GST_ELEMENT_NAME (basesink));
     GST_PREROLL_WAIT (pad);
-    GST_DEBUG ("done preroll");
+    GST_DEBUG_OBJECT (basesink, "done preroll");
   }
   GST_LOCK (pad);
   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
@@ -651,7 +651,7 @@ playing_async:
       g_warning ("STREAM_LOCK should have been locked !!");
     }
     GST_STATE_LOCK (basesink);
-    GST_DEBUG ("commit state %p >", basesink);
+    GST_DEBUG_OBJECT (basesink, "commit state");
     gst_element_commit_state (GST_ELEMENT (basesink));
     GST_STATE_UNLOCK (basesink);
     if (t > 0)
@@ -686,7 +686,7 @@ preroll_failed:
 
     /* now we abort our state */
     GST_STATE_LOCK (basesink);
-    GST_DEBUG ("abort state %p >", basesink);
+    GST_DEBUG_OBJECT (basesink, "abort state");
     gst_element_abort_state (GST_ELEMENT (basesink));
     GST_STATE_UNLOCK (basesink);
 
@@ -983,7 +983,7 @@ gst_base_sink_chain (GstPad * pad, GstBuffer * buf)
   return result;
 }
 
-/* FIXME, not all sinks can operate in pull mode 
+/* FIXME, not all sinks can operate in pull mode
  */
 static void
 gst_base_sink_loop (GstPad * pad)
index 0627a48..556520f 100644 (file)
@@ -203,7 +203,8 @@ G_STMT_START {                                                      \
   int rc;                                                      \
   rc = GST_OBJECT_REFCOUNT_VALUE (object);                     \
   fail_unless (rc == value,                                    \
-      "%s refcount is %d instead of %d", name, rc, value);     \
+      "%s (%p) refcount is %d instead of %d",                  \
+      name, object, rc, value);                                        \
 } G_STMT_END
 
 #define ASSERT_CAPS_REFCOUNT(caps, name, value)                        \
index a293e8d..655d9f0 100644 (file)
@@ -4,9 +4,14 @@ CHECK_REGISTRY = $(top_builddir)/check/test-registry.xml
 
 GST_TOOLS_DIR = $(top_builddir)/tools
 
-TESTS_ENVIRONMENT=\
+REGISTRY_ENVIRONMENT = \
        GST_REGISTRY=$(CHECK_REGISTRY)
 
+TESTS_ENVIRONMENT = \
+        $(REGISTRY_ENVIRONMENT)                                 \
+        GST_PLUGIN_PATH_ONLY=yes                                \
+        GST_PLUGIN_PATH=$(top_builddir)/gst
+
 plugindir = $(libdir)/gstreamer-@GST_MAJORMINOR@
 
 # rebuild gst-register-@GST_MAJORMINOR@ if needed
@@ -25,13 +30,9 @@ clean-local: clean-local-check
 
 $(CHECK_REGISTRY):
        $(TESTS_ENVIRONMENT)                                    \
-       GST_PLUGIN_PATH_ONLY=yes                                \
-       GST_PLUGIN_PATH=$(top_builddir)/gst                     \
-       $(top_builddir)/tools/gst-register
+       $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@
 
-# FIXME: it'd be nicer to run the versioned register, but in that case
-# "make dist" complains about not finding gst-register-0.9.c
-TESTS = $(top_builddir)/tools/gst-register     \
+check_PROGRAMS =                               \
        gst/gst                                 \
        gst/gstbin                              \
         gst/gstbuffer                          \
@@ -57,7 +58,8 @@ TESTS = $(top_builddir)/tools/gst-register    \
        gst-libs/controller                     \
        gst-libs/gdp
 
-check_PROGRAMS = $(TESTS)
+TESTS = $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@    \
+       $(check_PROGRAMS)
 
 noinst_HEADERS = gst/capslist.h
 
@@ -89,7 +91,7 @@ TESTS_THREADED =                              \
        gst/gstminiobject                       \
        gst/gstobject
 
-VALGRIND_TESTS_DISABLE =                       \
-       $(top_builddir)/tools/gst-register      \
-       $(TESTS_THREADED)                       \
+VALGRIND_TESTS_DISABLE =                                       \
+       $(top_builddir)/tools/gst-register-@GST_MAJORMINOR@     \
+       $(TESTS_THREADED)                                       \
        $(TESTS_TO_FIX)
index 61ae0d2..8394950 100644 (file)
@@ -221,26 +221,72 @@ GST_START_TEST (test_message_state_changed_children)
 
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
-  ASSERT_OBJECT_REFCOUNT (src, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
 
   bus = GST_ELEMENT_BUS (pipeline);
 
-  /* change state, spawning three times three messages */
+  /* change state to READY, spawning three 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 a message */
+  ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+  pop_messages (bus, 3);
+  fail_if ((gst_bus_pop (bus)) != NULL);
+
+  ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* change state to PAUSED, spawning three messages */
+  GST_DEBUG ("setting pipeline to PAUSED");
+  fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
+      == GST_STATE_SUCCESS);
+
+  /* each object is referenced by a message;
+   * base_sink_chain has taken a refcount on the sink, and is blocked on
+   * preroll */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+  pop_messages (bus, 3);
+  fail_if ((gst_bus_pop (bus)) != NULL);
+
+  ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+  ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+  /* change state to PLAYING, spawning 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);
+  /* each object is referenced by one message; sink still has an extra
+   * because it's still blocked on preroll */
+  ASSERT_OBJECT_REFCOUNT (src, "src", 2);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
+
+  pop_messages (bus, 3);
+  fail_if ((gst_bus_pop (bus)) != NULL);
 
-  /* this test is completely bogus as the refcount can change while running */
-#if 0
   ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
-  ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+  ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
-#endif
 
   /* go back to READY, spawning six messages */
+  /* FIXME: only now does the sink get unblocked from preroll
+   * (check log for "done preroll")
+   * mabe that's a bug ? */
   GST_DEBUG ("setting pipeline to READY");
   fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
       == GST_STATE_SUCCESS);
@@ -251,6 +297,7 @@ GST_START_TEST (test_message_state_changed_children)
   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
 
   pop_messages (bus, 6);
+  fail_if ((gst_bus_pop (bus)) != NULL);
 
   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);