[pygobject] Clean up caller-allocated GValues and their memory



commit 9a2060f26c2cc2f9ef79ab6fb9f512c317004856
Author: Mike Gorse <mgorse suse com>
Date:   Tue Jan 15 20:04:46 2013 -0600

    Clean up caller-allocated GValues and their memory
    
    When space for a GValue is allocated by the caller (as in
    gtk_tree_model_get_value), we need to free the space allocated for the
    value along with its contents. The GValue is not needed after
    Pyg_value_as_pyobject is called, so call _cleanup_caller_allocates and
    have it unset the value and deallocate the memory.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=691820

 gi/pygi-marshal-cleanup.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)
---
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index 0246f31..b4f5af3 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -24,20 +24,29 @@
 static inline void
 _cleanup_caller_allocates (PyGIInvokeState    *state,
                            PyGIArgCache       *cache,
-                           gpointer            data)
+                           gpointer            data,
+                           gboolean            was_processed)
 {
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)cache;
 
     if (iface_cache->g_type == G_TYPE_BOXED) {
         gsize size;
+        if (was_processed)
+            return; /* will be cleaned up at deallocation */
         size = g_struct_info_get_size (iface_cache->interface_info);
         g_slice_free1 (size, data);
     } else if (iface_cache->g_type == G_TYPE_VALUE) {
+        if (was_processed)
+            g_value_unset (data);
         g_slice_free (GValue, data);
     } else if (iface_cache->is_foreign) {
+        if (was_processed)
+            return; /* will be cleaned up at deallocation */
         pygi_struct_foreign_release ((GIBaseInfo *)iface_cache->interface_info,
                                      data);
     } else {
+        if (was_processed)
+            return; /* will be cleaned up at deallocation */
         g_free (data);
     }
 }
@@ -121,6 +130,12 @@ pygi_marshal_cleanup_args_to_py_marshal_success (PyGIInvokeState   *state,
                           arg_cache,
                           data,
                           TRUE);
+        else if (arg_cache->is_caller_allocates && data != NULL) {
+            _cleanup_caller_allocates (state,
+                                       arg_cache,
+                                       data,
+                                       TRUE);
+        }
 
         cache_item = cache_item->next;
     }
@@ -151,7 +166,8 @@ pygi_marshal_cleanup_args_from_py_parameter_fail (PyGIInvokeState   *state,
         } else if (arg_cache->is_caller_allocates && data != NULL) {
             _cleanup_caller_allocates (state,
                                        arg_cache,
-                                       data);
+                                       data,
+                                       FALSE);
         }
     }
 }



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