mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 12:49:40 +00:00
gstbus: fix refcounting in gst.Bus.set_sync_handler.
This commit is contained in:
parent
4eba960ed2
commit
0fd4db686b
2 changed files with 68 additions and 6 deletions
|
@ -155,8 +155,12 @@ override gst_bus_set_sync_handler args
|
|||
static PyObject *
|
||||
_wrap_gst_bus_set_sync_handler (PyGObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *callback, *cbargs = NULL, *data;
|
||||
PyObject *callback = NULL;
|
||||
PyObject *cbargs = NULL;
|
||||
PyObject *data = NULL;
|
||||
PyObject *old_data = NULL;
|
||||
gint len;
|
||||
static GQuark sync_handler_data_quark = 0;
|
||||
|
||||
len = PyTuple_Size(args);
|
||||
|
||||
|
@ -165,26 +169,54 @@ _wrap_gst_bus_set_sync_handler (PyGObject *self, PyObject *args)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (sync_handler_data_quark == 0)
|
||||
sync_handler_data_quark = \
|
||||
g_quark_from_static_string("PyGst::BusSyncHandlerData");
|
||||
|
||||
callback = PySequence_GetItem(args, 0);
|
||||
if (callback != Py_None) {
|
||||
if (!PyCallable_Check(callback)) {
|
||||
Py_DECREF (callback);
|
||||
PyErr_SetString(PyExc_TypeError, "callback is not callable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cbargs = PySequence_GetSlice(args, 1, len);
|
||||
if (cbargs == NULL)
|
||||
if (cbargs == NULL) {
|
||||
Py_DECREF (callback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = Py_BuildValue("(ON)", callback, cbargs);
|
||||
if (data == NULL)
|
||||
Py_DECREF (cbargs);
|
||||
if (data == NULL) {
|
||||
Py_DECREF (callback);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old_data = g_object_get_qdata (self->obj, sync_handler_data_quark);
|
||||
if (old_data != NULL) {
|
||||
Py_DECREF (old_data);
|
||||
}
|
||||
|
||||
g_object_set_qdata (self->obj, sync_handler_data_quark, data);
|
||||
|
||||
gst_bus_set_sync_handler (GST_BUS (self->obj),
|
||||
(GstBusSyncHandler) bus_sync_handler,
|
||||
(GstBusSyncHandler) bus_sync_handler,
|
||||
data);
|
||||
} else
|
||||
} else {
|
||||
old_data = g_object_get_qdata (self->obj, sync_handler_data_quark);
|
||||
if (old_data != NULL) {
|
||||
Py_DECREF (old_data);
|
||||
}
|
||||
|
||||
g_object_set_qdata (self->obj, sync_handler_data_quark, NULL);
|
||||
|
||||
gst_bus_set_sync_handler (GST_BUS (self->obj), NULL, NULL);
|
||||
}
|
||||
|
||||
Py_DECREF (callback);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ from common import gst, unittest, TestCase
|
|||
|
||||
import gobject
|
||||
import time
|
||||
import sys
|
||||
|
||||
class BusSignalTest(TestCase):
|
||||
def testGoodConstructor(self):
|
||||
|
@ -109,8 +110,37 @@ class BusSignalTest(TestCase):
|
|||
loop.quit()
|
||||
return True
|
||||
|
||||
def testSyncHandlerCallbackRefcount(self):
|
||||
def callback1():
|
||||
pass
|
||||
|
||||
def callback2():
|
||||
pass
|
||||
|
||||
bus = gst.Bus()
|
||||
|
||||
# set
|
||||
self.failUnless(sys.getrefcount(callback1), 2)
|
||||
bus.set_sync_handler(callback1)
|
||||
self.failUnless(sys.getrefcount(callback1), 3)
|
||||
|
||||
# set again
|
||||
self.failUnless(sys.getrefcount(callback1), 3)
|
||||
bus.set_sync_handler(callback1)
|
||||
self.failUnless(sys.getrefcount(callback1), 3)
|
||||
|
||||
# replace
|
||||
# this erros out in gst_bus_set_sync_handler, but we need to check that
|
||||
# we don't leak anyway
|
||||
self.failUnless(sys.getrefcount(callback2), 2)
|
||||
bus.set_sync_handler(callback2)
|
||||
self.failUnless(sys.getrefcount(callback1), 2)
|
||||
self.failUnless(sys.getrefcount(callback2), 3)
|
||||
|
||||
# unset
|
||||
bus.set_sync_handler(None)
|
||||
self.failUnless(sys.getrefcount(callback2), 2)
|
||||
|
||||
|
||||
class BusAddWatchTest(TestCase):
|
||||
|
||||
def testADumbExample(self):
|
||||
|
|
Loading…
Reference in a new issue