summaryrefslogtreecommitdiff
path: root/gi/pygi-boxed.c
diff options
context:
space:
mode:
authorSimon Feltman <sfeltman@src.gnome.org>2014-09-06 23:58:25 -0700
committerSimon Feltman <sfeltman@src.gnome.org>2014-09-08 13:58:57 -0700
commitd70b300c7415dd7b20ff88b09fe835690da19831 (patch)
tree7f3b87fa134d991c64b1f2b8722c63933d45cb23 /gi/pygi-boxed.c
parent09161ff690ad37c94668d5d65191f4d84829d41f (diff)
downloadpygobject-d70b300c7415dd7b20ff88b09fe835690da19831.tar.gz
Fix memory management problems with struct arguments to signals
Replicate struct marshaling logic for determining if struct arguments to signals should be passed by reference to callbacks. Maintain a list of these structs and apply an in-place copy of the struct pointer if the struct wrapper is held longer than the duration of the Python callback. This allows for both mutation of struct arguments from callbacks as well as memory safety incase a callbacks holds onto the struct. https://bugzilla.gnome.org/show_bug.cgi?id=736175
Diffstat (limited to 'gi/pygi-boxed.c')
-rw-r--r--gi/pygi-boxed.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index a1494b61..d5faeb1a 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -206,6 +206,26 @@ _pygi_boxed_get_free_on_dealloc(PyGIBoxed *self, void *closure)
return PyBool_FromLong( ((PyGBoxed *)self)->free_on_dealloc );
}
+/**
+ * _pygi_boxed_copy_in_place:
+ *
+ * Replace the boxed pointer held by this wrapper with a boxed copy
+ * freeing the previously held pointer (when free_on_dealloc is TRUE).
+ * This can be used in cases where Python is passed a reference which
+ * it does not own and the wrapper is held by the Python program
+ * longer than the duration of a callback it was passed to.
+ */
+void
+_pygi_boxed_copy_in_place (PyGIBoxed *self)
+{
+ PyGBoxed *pygboxed = (PyGBoxed *)self;
+ gpointer copy = g_boxed_copy (pygboxed->gtype, pyg_boxed_get_ptr (self));
+
+ boxed_del (self);
+ pyg_boxed_set_ptr (pygboxed, copy);
+ pygboxed->free_on_dealloc = TRUE;
+}
+
static PyGetSetDef pygi_boxed_getsets[] = {
{ "_free_on_dealloc", (getter)_pygi_boxed_get_free_on_dealloc, (setter)0 },
{ NULL, 0, 0 }