diff --git a/ChangeLog b/ChangeLog index b53e4291b9..3040a94f75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2008-02-10 Alessandro Decina + + reviewed by: Edward Hervey + * gst/gstpad.override: + * testsuite/test_pad.py: + Fix memleak in gst.Pad.set_blocked_async() + Fixes #514717 + 2008-02-10 Edward Hervey * gst/gstpad.override: diff --git a/gst/gstpad.override b/gst/gstpad.override index 8b32124115..6df09712d6 100644 --- a/gst/gstpad.override +++ b/gst/gstpad.override @@ -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(); diff --git a/testsuite/test_pad.py b/testsuite/test_pad.py index a5b3a1c472..d813536d2d 100644 --- a/testsuite/test_pad.py +++ b/testsuite/test_pad.py @@ -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()