gstreamer/gst/gstobject.override
Thomas Vander Stichele deb316e3fd gst/gstobject.override: don't try and unref objects that are already finalizing
Original commit message from CVS:

* gst/gstobject.override:
don't try and unref objects that are already finalizing
* gst/gstpad.override:
fix up the set_chainfunc method
* testsuite/common.py:
* testsuite/test_pad.py:
add linked/unlinked tests with no/true/false bufferprobes
2005-10-05 16:19:13 +00:00

180 lines
5 KiB
C

/* -*- Mode: C; ; c-file-style: "python" -*- */
/* gst-python
* Copyright (C) 2005 Edward Hervey
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Edward Hervey <edward@fluendo.com>
*/
%%
ignore
gst_object_default_deep_notify
gst_object_check_uniqueness
gst_object_replace
%%
override-attr GstObject.__gstrefcount__
/* keep this attribute around even after 2.8 for compatibility reasons */
static PyObject *
_wrap_gst_object__get___gstrefcount__(PyGObject *self, void *closure)
{
return PyInt_FromLong(GST_OBJECT_REFCOUNT_VALUE(self->obj));
}
/* < GLib 2.8 */
/* because of our gst_object_ref/_unref, we do our own GC-related
* functions:
* our own tp_traverse that checks the GstObject refcount,
* and reuse _dealloc and _clear from gobject.GObject for ours
* compare with pygtk/gobject/pygobject.c
*/
/* a define is a little evil, but it seems to generate the right code
* to allow us to do our garbage collection routines */
%%
override-slot GstObject.tp_flags
#define _wrap_gst_object_tp_flags Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC
%%
override-slot GstObject.tp_traverse
static int
_wrap_gst_object_tp_traverse(PyGObject *self, visitproc visit, void *arg)
{
int ret = 0;
GSList *tmp;
GST_LOG_OBJECT(self->obj,
"gst.Object.tp_traverse");
Py_VISIT(self->inst_dict);
for (tmp = self->closures; tmp != NULL; tmp = tmp->next) {
PyGClosure *closure = tmp->data;
Py_VISIT(closure->callback);
Py_VISIT(closure->extra_args);
Py_VISIT(closure->swap_data);
}
if (self->obj && GST_OBJECT_REFCOUNT_VALUE(self->obj) == 1 && GST_OBJECT(self->obj)->parent == NULL) {
GST_DEBUG_OBJECT(self->obj,
"gst.Object.tp_traverse: GstObject refcount of %p is 1, visit",
self->obj);
ret = visit((PyObject *)self, arg);
GST_LOG_OBJECT(self->obj,
"gst.Object.tp_traverse: GstObject %p visited, ret %d",
self->obj, ret);
}
return ret;
}
%%
override-slot GstObject.tp_clear
int
_wrap_gst_object_tp_clear(PyGObject *self)
{
int ret;
GObject *obj = self->obj;
/* if we're a GstObject, we want to monkeypatch the GObject.tp_clear's
* g_object_unref and "replace" it with a gst_object_unref */
if (! GST_IS_OBJECT (obj))
obj = NULL;
else {
GST_DEBUG_OBJECT (obj,
"gst.Object.tp_clear, pyo %p, pyo rc %d, gsto %p, gst rc %d",
self, ((PyObject *) self)->ob_refcnt, obj,
GST_OBJECT_REFCOUNT_VALUE (obj));
g_object_ref (obj);
}
ret = PyGObject_Type.tp_clear((PyObject *) self);
if (obj)
gst_object_unref (obj);
return ret;
}
%%
override-slot GstObject.tp_dealloc
void
_wrap_gst_object_tp_dealloc(PyGObject *self)
{
GObject *obj = self->obj;
/* if we're a GstObject, we want to monkeypatch the GObject.tp_dealloc's
* g_object_unref and "replace" it with a gst_object_unref */
if (GST_IS_OBJECT (obj)) {
GST_DEBUG_OBJECT (obj, "gst.Object.tp_dealloc, go rc %d, gsto rc %d",
obj->ref_count, GST_OBJECT_REFCOUNT_VALUE (obj));
if (GST_OBJECT_REFCOUNT_VALUE (obj) == 0) {
/* already being finalized, can't resurrect object */
obj = NULL;
self->obj = NULL;
} else {
g_object_ref (obj);
}
} else {
obj = NULL;
}
PyGObject_Type.tp_dealloc((PyObject *) self);
if (obj)
gst_object_unref (obj);
}
%%
override-slot GstObject.tp_repr
static PyObject *
_wrap_gst_object_tp_repr(PyObject *self)
{
gchar *repr;
PyObject *ret;
GstObject *object = GST_OBJECT (pygobject_get (self));
repr = g_strdup_printf ("<%s object (%s) at 0x%lx>",
self->ob_type->tp_name,
GST_OBJECT_NAME(object) ? GST_OBJECT_NAME(object) : "unnamed",
(long)self);
ret = PyString_FromString(repr);
g_free (repr);
return ret;
}
%%
override-slot GstObject.tp_str
static PyObject *
_wrap_gst_object_tp_str(PyObject *self)
{
gchar *repr, *path;
PyObject *ret;
GstObject *object = GST_OBJECT (pygobject_get (self));
path = gst_object_get_path_string (object);
repr = g_strdup_printf ("%s (%s)",
path, self->ob_type->tp_name);
ret = PyString_FromString(repr);
g_free (repr);
g_free (path);
return ret;
}