mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
gst/pygstminiobject.c: Dooh, PyGstMiniObject doesn't need cyclic garbage collection !
Original commit message from CVS: * gst/pygstminiobject.c: Dooh, PyGstMiniObject doesn't need cyclic garbage collection ! Bye, bye Python refcounting (and refcounting bugs).
This commit is contained in:
parent
64bc1f0c1b
commit
f4d65bd143
2 changed files with 23 additions and 59 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2005-10-06 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
|
* gst/pygstminiobject.c:
|
||||||
|
Dooh, PyGstMiniObject doesn't need cyclic garbage collection !
|
||||||
|
Bye, bye Python refcounting (and refcounting bugs).
|
||||||
|
|
||||||
2005-10-06 Thomas Vander Stichele <thomas at apestaart dot org>
|
2005-10-06 Thomas Vander Stichele <thomas at apestaart dot org>
|
||||||
|
|
||||||
* testsuite/test_ghostpad.py:
|
* testsuite/test_ghostpad.py:
|
||||||
|
|
|
@ -28,8 +28,8 @@ static GQuark pygstminiobject_class_key = 0;
|
||||||
/* static GQuark pygstminiobject_wrapper_key = 0; */
|
/* static GQuark pygstminiobject_wrapper_key = 0; */
|
||||||
|
|
||||||
static void pygstminiobject_dealloc(PyGstMiniObject *self);
|
static void pygstminiobject_dealloc(PyGstMiniObject *self);
|
||||||
static int pygstminiobject_traverse(PyGstMiniObject *self, visitproc visit, void *arg);
|
/* static int pygstminiobject_traverse(PyGstMiniObject *self, visitproc visit, void *arg); */
|
||||||
static int pygstminiobject_clear(PyGstMiniObject *self);
|
/* static int pygstminiobject_clear(PyGstMiniObject *self); */
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (pygst_debug);
|
GST_DEBUG_CATEGORY_EXTERN (pygst_debug);
|
||||||
#define GST_CAT_DEFAULT pygst_debug
|
#define GST_CAT_DEFAULT pygst_debug
|
||||||
|
@ -98,7 +98,7 @@ pygstminiobject_register_class(PyObject *dict, const gchar *type_name,
|
||||||
s = strrchr(class_name, '.');
|
s = strrchr(class_name, '.');
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
class_name = s + 1;
|
class_name = s + 1;
|
||||||
|
|
||||||
type->ob_type = &PyType_Type;
|
type->ob_type = &PyType_Type;
|
||||||
type->tp_alloc = PyType_GenericAlloc;
|
type->tp_alloc = PyType_GenericAlloc;
|
||||||
type->tp_new = PyType_GenericNew;
|
type->tp_new = PyType_GenericNew;
|
||||||
|
@ -115,9 +115,11 @@ pygstminiobject_register_class(PyObject *dict, const gchar *type_name,
|
||||||
if (gtype) {
|
if (gtype) {
|
||||||
o = pyg_type_wrapper_new(gtype);
|
o = pyg_type_wrapper_new(gtype);
|
||||||
PyDict_SetItemString(type->tp_dict, "__gtype__", o);
|
PyDict_SetItemString(type->tp_dict, "__gtype__", o);
|
||||||
|
GST_INFO ("Decrement refcount %p", o);
|
||||||
Py_DECREF(o);
|
Py_DECREF(o);
|
||||||
|
|
||||||
/* stash a pointer to the python class with the GType */
|
/* stash a pointer to the python class with the GType */
|
||||||
|
GST_INFO ("Increment refcount %p", type);
|
||||||
Py_INCREF(type);
|
Py_INCREF(type);
|
||||||
g_type_set_qdata(gtype, pygstminiobject_class_key, type);
|
g_type_set_qdata(gtype, pygstminiobject_class_key, type);
|
||||||
}
|
}
|
||||||
|
@ -142,7 +144,6 @@ pygstminiobject_register_wrapper (PyObject *self)
|
||||||
PyGILState_STATE state;
|
PyGILState_STATE state;
|
||||||
|
|
||||||
g_assert (obj);
|
g_assert (obj);
|
||||||
Py_INCREF (self);
|
|
||||||
GST_DEBUG ("inserting self %p in the table for object %p", self, obj);
|
GST_DEBUG ("inserting self %p in the table for object %p", self, obj);
|
||||||
state = pyg_gil_state_ensure ();
|
state = pyg_gil_state_ensure ();
|
||||||
g_hash_table_insert (_miniobjs, (gpointer) obj, (gpointer) self);
|
g_hash_table_insert (_miniobjs, (gpointer) obj, (gpointer) self);
|
||||||
|
@ -182,6 +183,7 @@ pygstminiobject_new (GstMiniObject *obj)
|
||||||
/* make sure the lookup returned our object */
|
/* make sure the lookup returned our object */
|
||||||
g_assert (self->obj);
|
g_assert (self->obj);
|
||||||
g_assert (self->obj == obj);
|
g_assert (self->obj == obj);
|
||||||
|
GST_INFO ("Increment refcount %p", self);
|
||||||
Py_INCREF (self);
|
Py_INCREF (self);
|
||||||
} else {
|
} else {
|
||||||
GST_DEBUG ("have to create wrapper for object %p", obj);
|
GST_DEBUG ("have to create wrapper for object %p", obj);
|
||||||
|
@ -189,11 +191,11 @@ pygstminiobject_new (GstMiniObject *obj)
|
||||||
PyTypeObject *tp = pygstminiobject_lookup_class (G_OBJECT_TYPE (obj));
|
PyTypeObject *tp = pygstminiobject_lookup_class (G_OBJECT_TYPE (obj));
|
||||||
if (!tp)
|
if (!tp)
|
||||||
g_warning ("Couldn't get class for type object : %p", obj);
|
g_warning ("Couldn't get class for type object : %p", obj);
|
||||||
/* need to bump type refcount if created with
|
if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE) {
|
||||||
pygstminiobject_new_with_interfaces(). fixes bug #141042 */
|
GST_INFO ("Increment refcount %p", tp);
|
||||||
if (tp->tp_flags & Py_TPFLAGS_HEAPTYPE)
|
|
||||||
Py_INCREF (tp);
|
Py_INCREF (tp);
|
||||||
self = PyObject_GC_New (PyGstMiniObject, tp);
|
}
|
||||||
|
self = PyObject_New (PyGstMiniObject, tp);
|
||||||
if (self == NULL)
|
if (self == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
self->obj = gst_mini_object_ref (obj);
|
self->obj = gst_mini_object_ref (obj);
|
||||||
|
@ -201,15 +203,12 @@ pygstminiobject_new (GstMiniObject *obj)
|
||||||
self->inst_dict = NULL;
|
self->inst_dict = NULL;
|
||||||
self->weakreflist = NULL;
|
self->weakreflist = NULL;
|
||||||
|
|
||||||
Py_INCREF (self);
|
|
||||||
|
|
||||||
/* save wrapper pointer so we can access it later */
|
/* save wrapper pointer so we can access it later */
|
||||||
GST_DEBUG ("inserting self %p in the table for object %p", self, obj);
|
GST_DEBUG ("inserting self %p in the table for object %p", self, obj);
|
||||||
state = pyg_gil_state_ensure ();
|
state = pyg_gil_state_ensure ();
|
||||||
g_hash_table_insert (_miniobjs, (gpointer) obj, (gpointer) self);
|
g_hash_table_insert (_miniobjs, (gpointer) obj, (gpointer) self);
|
||||||
pyg_gil_state_release (state);
|
pyg_gil_state_release (state);
|
||||||
|
|
||||||
PyObject_GC_Track ((PyObject *)self);
|
|
||||||
}
|
}
|
||||||
return (PyObject *) self;
|
return (PyObject *) self;
|
||||||
}
|
}
|
||||||
|
@ -221,15 +220,10 @@ pygstminiobject_dealloc(PyGstMiniObject *self)
|
||||||
|
|
||||||
PyGILState_STATE state;
|
PyGILState_STATE state;
|
||||||
|
|
||||||
|
GST_INFO ("At the beginning %p", self);
|
||||||
state = pyg_gil_state_ensure();
|
state = pyg_gil_state_ensure();
|
||||||
|
|
||||||
PyObject_ClearWeakRefs((PyObject *)self);
|
|
||||||
|
|
||||||
PyObject_GC_UnTrack((PyObject *)self);
|
|
||||||
|
|
||||||
if (self->obj) {
|
if (self->obj) {
|
||||||
/* the following causes problems with subclassed types */
|
|
||||||
/* self->ob_type->tp_free((PyObject *)self); */
|
|
||||||
GST_DEBUG ("removing self %p from the table for object %p", self,
|
GST_DEBUG ("removing self %p from the table for object %p", self,
|
||||||
self->obj);
|
self->obj);
|
||||||
g_assert (g_hash_table_remove (_miniobjs, (gpointer) self->obj));
|
g_assert (g_hash_table_remove (_miniobjs, (gpointer) self->obj));
|
||||||
|
@ -243,8 +237,9 @@ pygstminiobject_dealloc(PyGstMiniObject *self)
|
||||||
}
|
}
|
||||||
self->inst_dict = NULL;
|
self->inst_dict = NULL;
|
||||||
|
|
||||||
PyObject_GC_Del(self);
|
self->ob_type->tp_free((PyObject *) self);
|
||||||
pyg_gil_state_release(state);
|
pyg_gil_state_release(state);
|
||||||
|
GST_INFO ("At the end %p", self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -274,47 +269,11 @@ pygstminiobject_repr(PyGstMiniObject *self)
|
||||||
return PyString_FromString(buf);
|
return PyString_FromString(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
pygstminiobject_traverse(PyGstMiniObject *self, visitproc visit, void *arg)
|
|
||||||
{
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (self->inst_dict) ret = visit(self->inst_dict, arg);
|
|
||||||
if (ret != 0) return ret;
|
|
||||||
|
|
||||||
if (self->obj && self->obj->refcount == 1)
|
|
||||||
ret = visit((PyObject *)self, arg);
|
|
||||||
if (ret != 0) return ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
pygstminiobject_clear(PyGstMiniObject *self)
|
|
||||||
{
|
|
||||||
if (self->inst_dict) {
|
|
||||||
Py_DECREF(self->inst_dict);
|
|
||||||
}
|
|
||||||
self->inst_dict = NULL;
|
|
||||||
|
|
||||||
if (self->obj) {
|
|
||||||
/* the following causes problems with subclassed types */
|
|
||||||
/* self->ob_type->tp_free((PyObject *)self); */
|
|
||||||
GST_DEBUG ("removing self %p from the table for object %p", self,
|
|
||||||
self->obj);
|
|
||||||
g_assert (g_hash_table_remove (_miniobjs, (gpointer) self->obj));
|
|
||||||
gst_mini_object_unref (self->obj);
|
|
||||||
}
|
|
||||||
GST_DEBUG ("setting self %p -> obj to NULL", self);
|
|
||||||
self->obj = NULL;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pygstminiobject_free(PyObject *op)
|
pygstminiobject_free(PyObject *op)
|
||||||
{
|
{
|
||||||
PyObject_GC_Del(op);
|
PyObject_FREE(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -429,11 +388,10 @@ PyTypeObject PyGstMiniObject_Type = {
|
||||||
(getattrofunc)0, /* tp_getattro */
|
(getattrofunc)0, /* tp_getattro */
|
||||||
(setattrofunc)0, /* tp_setattro */
|
(setattrofunc)0, /* tp_setattro */
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
|
||||||
NULL, /* Documentation string */
|
NULL, /* Documentation string */
|
||||||
(traverseproc)pygstminiobject_traverse, /* tp_traverse */
|
(traverseproc)0, /* tp_traverse */
|
||||||
(inquiry)pygstminiobject_clear, /* tp_clear */
|
(inquiry)0, /* tp_clear */
|
||||||
(richcmpfunc)0, /* tp_richcompare */
|
(richcmpfunc)0, /* tp_richcompare */
|
||||||
offsetof(PyGstMiniObject, weakreflist), /* tp_weaklistoffset */
|
offsetof(PyGstMiniObject, weakreflist), /* tp_weaklistoffset */
|
||||||
(getiterfunc)0, /* tp_iter */
|
(getiterfunc)0, /* tp_iter */
|
||||||
|
|
Loading…
Reference in a new issue