Fix memleak in gst.Pad.set_blocked_async()
authorEdward Hervey <bilboed@bilboed.com>
Sun, 10 Feb 2008 13:33:26 +0000 (13:33 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Sun, 10 Feb 2008 13:33:26 +0000 (13:33 +0000)
Original commit message from CVS:
reviewed by: Edward Hervey  <edward.hervey@collabora.co.uk>
* gst/gstpad.override:
* testsuite/test_pad.py:
Fix memleak in gst.Pad.set_blocked_async()
Fixes #514717

ChangeLog
gst/gstpad.override
testsuite/test_pad.py

index b53e429..3040a94 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-02-10  Alessandro Decina  <alessandro@nnva.org>
+
+       reviewed by: Edward Hervey  <edward.hervey@collabora.co.uk>
+       * gst/gstpad.override:
+       * testsuite/test_pad.py:
+       Fix memleak in gst.Pad.set_blocked_async()
+       Fixes #514717
+       
 2008-02-10  Edward Hervey  <edward.hervey@collabora.co.uk>
 
        * gst/gstpad.override:
index 8b32124..6df0971 100644 (file)
@@ -1343,6 +1343,7 @@ pad_block_callback_marshal(GstPad *pad, gboolean blocked, gpointer user_data)
 
     ret = PyObject_CallObject(callback, args);
     Py_DECREF(args);
+    Py_DECREF(py_user_data);
 
     if (!ret)
         PyErr_Print();
index a5b3a1c..d813536 100644 (file)
@@ -516,5 +516,38 @@ class PadRefCountTest(TestCase):
             self.assertEquals(self.gccollect(), 1) # collected the pad
         gst.debug('going into teardown')
 
+class PadBlockRefcountTest(TestCase):
+    def testCallbackRefcount(self):
+        def blocked_cb(pad, blocked):
+            self.assertTrue(pad.set_blocked_async(False, unblocked_cb))
+
+        def unblocked_cb(pad, blocked):
+            pass
+
+        cb_refcount = sys.getrefcount(blocked_cb)
+        # sys.getrefcount() returns refcount + 1
+        self.assertEquals(cb_refcount, 2)
+
+        fakesrc = gst.element_factory_make('fakesrc')
+        fakesrc.props.num_buffers = 2
+        fakesink = gst.element_factory_make('fakesink')
+
+        pipeline = gst.Pipeline()
+        pipeline.add(fakesrc, fakesink)
+
+        fakesrc.link(fakesink)
+
+        pad = fakesrc.get_pad('src')
+        pad.set_blocked_async(True, blocked_cb)
+
+        pipeline.set_state(gst.STATE_PLAYING)
+        pipeline.get_bus().poll(gst.MESSAGE_EOS, -1)
+        pipeline.set_state(gst.STATE_NULL)
+
+        # check that we don't leak a ref to the callback
+        cb_refcount_after = sys.getrefcount(blocked_cb)
+        self.assertEquals(cb_refcount_after, cb_refcount)
+
+
 if __name__ == "__main__":
     unittest.main()