[pygobject] Fix leak of caller-allocated boxed values
- From: Martin Pitt <martinpitt src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pygobject] Fix leak of caller-allocated boxed values
- Date: Thu, 28 Feb 2013 11:29:23 +0000 (UTC)
commit 105e6738ee249b64904da26ae45dd273ca4eeba8
Author: Martin Pitt <martinpitt gnome org>
Date: Thu Feb 28 11:43:47 2013 +0100
Fix leak of caller-allocated boxed values
Add a new "allocated_slice" argument to _pygi_boxed_new() which specifies
whether its "boxed" pointer was allocated using a slice (by giving its size) or
malloc (by specifying 0), as _pygi_boxed_new cannot determine that itself any
more.
Use this in _pygi_marshal_to_py_interface_struct() for caller-allocated boxed
values, as _caller_alloc() uses _pygi_boxed_alloc() for those (i. e. slices),
which would otherwise leak.
Thanks to Mike Gorse <mgorse suse com> for the original patch!
https://bugzilla.gnome.org/show_bug.cgi?id=691501
gi/gimodule.c | 2 +-
gi/pygi-argument.c | 2 +-
gi/pygi-boxed.c | 14 ++++++++++----
gi/pygi-boxed.h | 3 ++-
gi/pygi-marshal-to-py.c | 6 ++++--
gi/pygi-source.c | 3 ++-
6 files changed, 20 insertions(+), 10 deletions(-)
---
diff --git a/gi/gimodule.c b/gi/gimodule.c
index 23b4d9b..108fc77 100644
--- a/gi/gimodule.c
+++ b/gi/gimodule.c
@@ -513,7 +513,7 @@ _wrap_pyg_variant_type_from_string (PyObject *self, PyObject *args)
py_type = _pygi_type_import_by_name ("GLib", "VariantType");
- py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE);
+ py_variant = _pygi_boxed_new ( (PyTypeObject *) py_type, type_string, FALSE, 0);
return py_variant;
}
diff --git a/gi/pygi-argument.c b/gi/pygi-argument.c
index 8dd7842..df2c54d 100644
--- a/gi/pygi-argument.c
+++ b/gi/pygi-argument.c
@@ -1752,7 +1752,7 @@ _pygi_argument_to_object (GIArgument *arg,
if (py_type == NULL)
break;
- object = _pygi_boxed_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer ==
GI_TRANSFER_EVERYTHING);
+ object = _pygi_boxed_new ( (PyTypeObject *) py_type, arg->v_pointer, transfer ==
GI_TRANSFER_EVERYTHING, 0);
Py_DECREF (py_type);
} else if (g_type_is_a (type, G_TYPE_POINTER)) {
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index c15c927..cac2b0d 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -104,7 +104,7 @@ _boxed_new (PyTypeObject *type,
goto out;
}
- self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE);
+ self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE, size);
if (self == NULL) {
g_slice_free1 (size, boxed);
goto out;
@@ -133,7 +133,8 @@ PYGLIB_DEFINE_TYPE("gi.Boxed", PyGIBoxed_Type, PyGIBoxed);
PyObject *
_pygi_boxed_new (PyTypeObject *type,
gpointer boxed,
- gboolean free_on_dealloc)
+ gboolean free_on_dealloc,
+ gsize allocated_slice)
{
PyGIBoxed *self;
@@ -154,8 +155,13 @@ _pygi_boxed_new (PyTypeObject *type,
( (PyGBoxed *) self)->gtype = pyg_type_from_object ( (PyObject *) type);
( (PyGBoxed *) self)->boxed = boxed;
( (PyGBoxed *) self)->free_on_dealloc = free_on_dealloc;
- self->size = 0;
- self->slice_allocated = FALSE;
+ if (allocated_slice > 0) {
+ self->size = allocated_slice;
+ self->slice_allocated = TRUE;
+ } else {
+ self->size = 0;
+ self->slice_allocated = FALSE;
+ }
return (PyObject *) self;
}
diff --git a/gi/pygi-boxed.h b/gi/pygi-boxed.h
index a84ec4e..38ac928 100644
--- a/gi/pygi-boxed.h
+++ b/gi/pygi-boxed.h
@@ -30,7 +30,8 @@ extern PyTypeObject PyGIBoxed_Type;
PyObject * _pygi_boxed_new (PyTypeObject *type,
gpointer boxed,
- gboolean free_on_dealloc);
+ gboolean free_on_dealloc,
+ gsize allocated_slice);
void * _pygi_boxed_alloc (GIBaseInfo *info,
gsize *size);
diff --git a/gi/pygi-marshal-to-py.c b/gi/pygi-marshal-to-py.c
index 661befc..693d2ea 100644
--- a/gi/pygi-marshal-to-py.c
+++ b/gi/pygi-marshal-to-py.c
@@ -814,8 +814,10 @@ _pygi_marshal_to_py_interface_struct (PyGIInvokeState *state,
py_obj = pygi_struct_foreign_convert_from_g_argument (iface_cache->interface_info,
arg->v_pointer);
} else if (g_type_is_a (type, G_TYPE_BOXED)) {
- py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
- arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+ py_obj = _pygi_boxed_new ( (PyTypeObject *)iface_cache->py_type, arg->v_pointer,
+ arg_cache->transfer == GI_TRANSFER_EVERYTHING ||
arg_cache->is_caller_allocates,
+ arg_cache->is_caller_allocates ?
+ g_struct_info_get_size(iface_cache->interface_info) : 0);
} else if (g_type_is_a (type, G_TYPE_POINTER)) {
if (iface_cache->py_type == NULL ||
!PyType_IsSubtype ( (PyTypeObject *)iface_cache->py_type, &PyGIStruct_Type)) {
diff --git a/gi/pygi-source.c b/gi/pygi-source.c
index b713b73..66bbc3c 100644
--- a/gi/pygi-source.c
+++ b/gi/pygi-source.c
@@ -240,7 +240,8 @@ pyg_source_new (void)
source = (PyGRealSource*) g_source_new (&pyg_source_funcs, sizeof (PyGRealSource));
py_type = _pygi_type_import_by_name ("GLib", "Source");
- source->obj = _pygi_boxed_new ( (PyTypeObject *) py_type, source, FALSE);
+ /* g_source_new uses malloc, not slices */
+ source->obj = _pygi_boxed_new ( (PyTypeObject *) py_type, source, FALSE, 0);
return source->obj;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]