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:
Edward Hervey 2005-10-06 10:51:55 +00:00
parent 64bc1f0c1b
commit f4d65bd143
2 changed files with 23 additions and 59 deletions

View file

@ -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:

View file

@ -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 */