Index: libs/gst/base/gstdataqueue.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstdataqueue.c,v
retrieving revision 1.2
diff -u -p -r1.2 gstdataqueue.c
--- libs/gst/base/gstdataqueue.c	24 May 2007 12:19:01 -0000	1.2
+++ libs/gst/base/gstdataqueue.c	24 May 2007 12:21:57 -0000
@@ -397,6 +397,11 @@ gst_data_queue_set_flushing (GstDataQueu
  * available, OR the @queue is set to flushing state.
  * MT safe.
  *
+ * Note that this function has slightly different semantics than gst_pad_push()
+ * and gst_pad_push_event(): this function only takes ownership of @item and
+ * the #GstMiniObject contained in @item if the push was successful. If FALSE
+ * is returned, the caller is responsible for freeing @item and its contents.
+ *
  * Returns: #TRUE if the @item was successfully pushed on the @queue.
  */
 gboolean
Index: libs/gst/base/gstdataqueue.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gstdataqueue.h,v
retrieving revision 1.1
diff -u -p -r1.1 gstdataqueue.h
--- libs/gst/base/gstdataqueue.h	28 Nov 2006 12:07:06 -0000	1.1
+++ libs/gst/base/gstdataqueue.h	24 May 2007 12:21:58 -0000
@@ -48,7 +48,9 @@ typedef struct _GstDataQueueItem GstData
  * @duration: the duration in #GstClockTime of the miniobject. Can not be
  * #GST_CLOCK_TIME_NONE.
  * @visible: #TRUE if @object should be considered as a visible object.
- * @destroy: The #GDestroyNotify to use to free the #GstDataQueueItem.
+ * @destroy: The #GDestroyNotify function to use to free the #GstDataQueueItem.
+ * This function should also drop the reference to @object the owner of the
+ * #GstDataQueueItem is assumed to hold.
  *
  * Structure used by #GstDataQueue. You can supply a different structure, as
  * long as the top of the structure is identical to this structure.
Index: plugins/elements/gstmultiqueue.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/plugins/elements/gstmultiqueue.c,v
retrieving revision 1.8
diff -u -p -r1.8 gstmultiqueue.c
--- plugins/elements/gstmultiqueue.c	13 Apr 2007 11:20:48 -0000	1.8
+++ plugins/elements/gstmultiqueue.c	24 May 2007 12:21:58 -0000
@@ -427,7 +427,10 @@ gst_single_queue_push_one (GstMultiQueue
     GstMiniObject * object)
 {
   if (GST_IS_BUFFER (object)) {
-    sq->srcresult = gst_pad_push (sq->srcpad, GST_BUFFER (object));
+    GstBuffer *buf;
+
+    buf = gst_buffer_ref (GST_BUFFER_CAST (object));
+    sq->srcresult = gst_pad_push (sq->srcpad, buf);
 
     if ((sq->srcresult != GST_FLOW_OK)
         && (sq->srcresult != GST_FLOW_NOT_LINKED)) {
@@ -437,7 +440,10 @@ gst_single_queue_push_one (GstMultiQueue
       gst_pad_pause_task (sq->srcpad);
     }
   } else if (GST_IS_EVENT (object)) {
-    if (GST_EVENT_TYPE (object) == GST_EVENT_EOS) {
+    GstEvent *event;
+
+    event = gst_event_ref (GST_EVENT_CAST (object));
+    if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
       sq->srcresult = GST_FLOW_UNEXPECTED;
 
       GST_DEBUG_OBJECT (mq, "GstSingleQueue %d : pausing queue, got EOS",
@@ -445,7 +451,7 @@ gst_single_queue_push_one (GstMultiQueue
       gst_data_queue_set_flushing (sq->queue, TRUE);
       gst_pad_pause_task (sq->srcpad);
     }
-    gst_pad_push_event (sq->srcpad, GST_EVENT (object));
+    gst_pad_push_event (sq->srcpad, event);
   } else {
     g_warning ("Unexpected object in singlequeue %d (refcounting problem?)",
         sq->id);
@@ -461,13 +467,14 @@ gst_multi_queue_item_destroy (GstMultiQu
   g_free (item);
 }
 
+/* takes ownership of passed mini object! */
 static GstMultiQueueItem *
 gst_multi_queue_item_new (GstMiniObject * object)
 {
   GstMultiQueueItem *item;
 
   item = g_new0 (GstMultiQueueItem, 1);
-  item->object = gst_mini_object_ref (object);
+  item->object = object;
   item->destroy = (GDestroyNotify) gst_multi_queue_item_destroy;
 
   if (GST_IS_BUFFER (object)) {
@@ -621,7 +628,6 @@ gst_multi_queue_chain (GstPad * pad, Gst
     GST_LOG_OBJECT (mq, "SingleQueue %d : exit because task paused, reason: %s",
         sq->id, gst_flow_get_name (sq->srcresult));
     gst_multi_queue_item_destroy (item);
-    gst_buffer_unref (buffer);
     ret = sq->srcresult;
   }
 
@@ -718,7 +724,6 @@ gst_multi_queue_sink_event (GstPad * pad
     GST_LOG_OBJECT (mq, "SingleQueue %d : exit because task paused, reason: %s",
         sq->id, gst_flow_get_name (sq->srcresult));
     gst_multi_queue_item_destroy (item);
-    gst_event_unref (event);
   }
 
 done:
Index: tests/check/elements/multiqueue.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/tests/check/elements/multiqueue.c,v
retrieving revision 1.1
diff -u -p -r1.1 multiqueue.c
--- tests/check/elements/multiqueue.c	28 Mar 2007 18:38:11 -0000	1.1
+++ tests/check/elements/multiqueue.c	24 May 2007 12:21:58 -0000
@@ -259,11 +259,7 @@ multiqueue_suite (void)
   suite_add_tcase (s, tc_chain);
   tcase_add_test (tc_chain, test_simple_create_destroy);
   tcase_add_test (tc_chain, test_simple_pipeline);
-
-  if (0) {
-    /* FIXME: this leaks buffers, disabled for now */
-    tcase_add_test (tc_chain, test_simple_shutdown_while_running);
-  }
+  tcase_add_test (tc_chain, test_simple_shutdown_while_running);
 
   /* FIXME: test_request_pads() needs some more fixes, see comments there */
   tcase_add_test (tc_chain, test_request_pads);
