mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 04:36:20 +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 *
|
static PyObject *
|
||||||
_wrap_gst_bus_set_sync_handler (PyGObject *self, PyObject *args)
|
_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;
|
gint len;
|
||||||
|
static GQuark sync_handler_data_quark = 0;
|
||||||
|
|
||||||
len = PyTuple_Size(args);
|
len = PyTuple_Size(args);
|
||||||
|
|
||||||
|
@ -165,26 +169,54 @@ _wrap_gst_bus_set_sync_handler (PyGObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sync_handler_data_quark == 0)
|
||||||
|
sync_handler_data_quark = \
|
||||||
|
g_quark_from_static_string("PyGst::BusSyncHandlerData");
|
||||||
|
|
||||||
callback = PySequence_GetItem(args, 0);
|
callback = PySequence_GetItem(args, 0);
|
||||||
if (callback != Py_None) {
|
if (callback != Py_None) {
|
||||||
if (!PyCallable_Check(callback)) {
|
if (!PyCallable_Check(callback)) {
|
||||||
|
Py_DECREF (callback);
|
||||||
PyErr_SetString(PyExc_TypeError, "callback is not callable");
|
PyErr_SetString(PyExc_TypeError, "callback is not callable");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbargs = PySequence_GetSlice(args, 1, len);
|
cbargs = PySequence_GetSlice(args, 1, len);
|
||||||
if (cbargs == NULL)
|
if (cbargs == NULL) {
|
||||||
|
Py_DECREF (callback);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
data = Py_BuildValue("(ON)", callback, cbargs);
|
data = Py_BuildValue("(ON)", callback, cbargs);
|
||||||
if (data == NULL)
|
Py_DECREF (cbargs);
|
||||||
|
if (data == NULL) {
|
||||||
|
Py_DECREF (callback);
|
||||||
return NULL;
|
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),
|
gst_bus_set_sync_handler (GST_BUS (self->obj),
|
||||||
(GstBusSyncHandler) bus_sync_handler,
|
(GstBusSyncHandler) bus_sync_handler,
|
||||||
data);
|
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);
|
gst_bus_set_sync_handler (GST_BUS (self->obj), NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_DECREF (callback);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ from common import gst, unittest, TestCase
|
||||||
|
|
||||||
import gobject
|
import gobject
|
||||||
import time
|
import time
|
||||||
|
import sys
|
||||||
|
|
||||||
class BusSignalTest(TestCase):
|
class BusSignalTest(TestCase):
|
||||||
def testGoodConstructor(self):
|
def testGoodConstructor(self):
|
||||||
|
@ -109,8 +110,37 @@ class BusSignalTest(TestCase):
|
||||||
loop.quit()
|
loop.quit()
|
||||||
return True
|
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):
|
class BusAddWatchTest(TestCase):
|
||||||
|
|
||||||
def testADumbExample(self):
|
def testADumbExample(self):
|
||||||
|
|
Loading…
Reference in a new issue