[pygobject] add a floating flag to pygobjects
- From: John Palmieri <johnp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] add a floating flag to pygobjects
- Date: Thu, 22 Sep 2011 02:20:42 +0000 (UTC)
commit 311a4f8035a95b41bc3c0a836c32b7a5bf2d9959
Author: John (J5) Palmieri <johnp redhat com>
Date: Wed Sep 21 21:50:48 2011 -0400
add a floating flag to pygobjects
* this allows us to correctly refcount when custom gobjects are instantiated
via g_object_new
gi/_gobject/gobjectmodule.c | 5 +++++
gi/_gobject/pygobject-private.h | 3 +++
gi/_gobject/pygobject.c | 27 ++++++++++++++++++++++++++-
gi/_gobject/pygobject.h | 3 ++-
4 files changed, 36 insertions(+), 2 deletions(-)
---
diff --git a/gi/_gobject/gobjectmodule.c b/gi/_gobject/gobjectmodule.c
index 2548f69..ac065a5 100644
--- a/gi/_gobject/gobjectmodule.c
+++ b/gi/_gobject/gobjectmodule.c
@@ -1066,6 +1066,11 @@ pygobject__g_instance_init(GTypeInstance *instance,
PyGILState_STATE state;
state = pyglib_gil_state_ensure();
wrapper = pygobject_new_full(object, FALSE, g_class);
+
+ /* float the wrapper ref here because we are going to orphan it
+ * so we don't destroy the wrapper. The next call to pygobject_new_full
+ * will take the ref */
+ pygobject_ref_float (wrapper);
args = PyTuple_New(0);
kwargs = PyDict_New();
if (Py_TYPE(wrapper)->tp_init(wrapper, args, kwargs))
diff --git a/gi/_gobject/pygobject-private.h b/gi/_gobject/pygobject-private.h
index dabf0a4..1b1d6db 100644
--- a/gi/_gobject/pygobject-private.h
+++ b/gi/_gobject/pygobject-private.h
@@ -96,6 +96,9 @@ PyObject *pyg_integer_richcompare(PyObject *v,
gboolean pyg_gerror_exception_check(GError **error);
+void pygobject_ref_float(PyGObject *self);
+void pygobject_ref_sink(PyGObject *self);
+
/* from pygtype.h */
extern PyTypeObject PyGTypeWrapper_Type;
diff --git a/gi/_gobject/pygobject.c b/gi/_gobject/pygobject.c
index 48a9f18..0f0e5e2 100644
--- a/gi/_gobject/pygobject.c
+++ b/gi/_gobject/pygobject.c
@@ -560,6 +560,31 @@ pygobject_switch_to_toggle_ref(PyGObject *self)
g_object_unref(self->obj);
}
+/* Called when an custom gobject is initalized via g_object_new instead of
+ its constructor. The next time the wrapper is access via
+ pygobject_new_full it will sink the floating reference instead of
+ adding a new reference and causing a leak */
+
+void
+pygobject_ref_float(PyGObject *self)
+{
+ /* should only be floated once */
+ g_assert(!(self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF));
+
+ self->private_flags.flags |= PYGOBJECT_IS_FLOATING_REF;
+}
+
+/* Called by gobject_new_full, if the floating flag is set remove it, otherwise
+ ref the pyobject */
+void
+pygobject_ref_sink(PyGObject *self)
+{
+ if (self->private_flags.flags & PYGOBJECT_IS_FLOATING_REF)
+ self->private_flags.flags &= ~PYGOBJECT_IS_FLOATING_REF;
+ else
+ Py_INCREF ( (PyObject *) self);
+}
+
/**
* pygobject_register_wrapper:
* @self: the wrapper instance
@@ -888,7 +913,7 @@ pygobject_new_full(GObject *obj, gboolean sink, gpointer g_class)
/* we already have a wrapper for this object -- return it. */
self = (PyGObject *)g_object_get_qdata(obj, pygobject_wrapper_key);
if (self != NULL) {
- Py_INCREF(self);
+ pygobject_ref_sink(self);
} else {
/* create wrapper */
PyGObjectData *inst_data = pyg_object_peek_inst_data(obj);
diff --git a/gi/_gobject/pygobject.h b/gi/_gobject/pygobject.h
index f728e15..8879fd0 100644
--- a/gi/_gobject/pygobject.h
+++ b/gi/_gobject/pygobject.h
@@ -23,7 +23,8 @@ struct _PyGClosure {
};
typedef enum {
- PYGOBJECT_USING_TOGGLE_REF = 1 << 0
+ PYGOBJECT_USING_TOGGLE_REF = 1 << 0,
+ PYGOBJECT_IS_FLOATING_REF = 1 << 1
} PyGObjectFlags;
/* closures is just an alias for what is found in the
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]