diff options
| author | Simon Feltman <sfeltman@src.gnome.org> | 2014-09-06 23:58:25 -0700 |
|---|---|---|
| committer | Simon Feltman <sfeltman@src.gnome.org> | 2014-09-08 13:58:57 -0700 |
| commit | d70b300c7415dd7b20ff88b09fe835690da19831 (patch) | |
| tree | 7f3b87fa134d991c64b1f2b8722c63933d45cb23 /gi/pygi-boxed.c | |
| parent | 09161ff690ad37c94668d5d65191f4d84829d41f (diff) | |
| download | pygobject-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.c | 20 |
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 } |
