[pygobject] Fix memory leaks for inout array arguments



commit d866d422cc39b229f443dd08a3ea50cb3f7df8e6
Author: Simon Feltman <sfeltman src gnome org>
Date:   Mon Oct 7 01:17:08 2013 -0700

    Fix memory leaks for inout array arguments
    
    Add tracking for array allocations to from_py marashalers in the
    argument states extra data (arg_data). This is then used later for inout
    marshaling cleanup to call the array cleanup function.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=693402

 gi/pygi-invoke.c          |    1 +
 gi/pygi-marshal-cleanup.c |    1 +
 gi/pygi-marshal-from-py.c |   13 +++++++++----
 3 files changed, 11 insertions(+), 4 deletions(-)
---
diff --git a/gi/pygi-invoke.c b/gi/pygi-invoke.c
index 2303638..eab6c2e 100644
--- a/gi/pygi-invoke.c
+++ b/gi/pygi-invoke.c
@@ -523,6 +523,7 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache)
                                                               arg_cache,
                                                               py_arg,
                                                               c_arg);
+
             if (!success) {
                 pygi_marshal_cleanup_args_from_py_parameter_fail (state,
                                                                   cache,
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index c5dfc6a..cd059a4 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -110,6 +110,7 @@ pygi_marshal_cleanup_args_from_py_marshal_success (PyGIInvokeState   *state,
                 arg_cache->direction == PYGI_DIRECTION_BIDIRECTIONAL &&
                     state->args_data[i] != NULL) {
             cleanup_func (state, arg_cache, py_arg, state->args_data[i], TRUE);
+            state->args_data[i] = NULL;
         }
     }
 }
diff --git a/gi/pygi-marshal-from-py.c b/gi/pygi-marshal-from-py.c
index 7665d4d..f257ecd 100644
--- a/gi/pygi-marshal-from-py.c
+++ b/gi/pygi-marshal-from-py.c
@@ -911,14 +911,19 @@ array_success:
     if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
         arg->v_pointer = array_->data;
         g_array_free (array_, FALSE);
-        /* remember the originally allocated array in args_data, as args and
-         * in_args get changed for (inout) arguments */
-        if (arg_cache->transfer == GI_TRANSFER_NOTHING)
-            state->args_data[arg_cache->c_arg_index] = arg->v_pointer;
     } else {
         arg->v_pointer = array_;
     }
 
+    /* Store the allocated array in the arguments extra data for bi-directional
+     * marshaling cleanup. This is needed because arg->v_pointer will be
+     * clobbered by the caller and we would have no way to clean it up later.
+     * TODO: This should go in the outer layer and apply generically at some point.
+     */
+    if (arg_cache->transfer == GI_TRANSFER_NOTHING) {
+        state->args_data[arg_cache->c_arg_index] = arg->v_pointer;
+    }
+
     return TRUE;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]