[pygobject/invoke-rewrite] [gi-invoke-ng] add out array cleanup



commit 601aec11c49e821fe97dd30a2187fe3c75844712
Author: John (J5) Palmieri <johnp redhat com>
Date:   Thu May 26 16:09:38 2011 -0400

    [gi-invoke-ng] add out array cleanup

 gi/pygi-cache.c           |    2 +-
 gi/pygi-marshal-cleanup.c |   24 ++++++++++++++++++++++++
 gi/pygi-marshal.c         |   37 +++++++++++++++++++++++++++++++------
 3 files changed, 56 insertions(+), 7 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 98e4607..a892655 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -540,6 +540,7 @@ _arg_cache_out_array_setup (PyGIArgCache *arg_cache,
 {
     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
     arg_cache->out_marshaller = _pygi_marshal_out_array;
+    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_array;
 
     seq_cache->array_type = g_type_info_get_array_type (type_info);
 
@@ -567,7 +568,6 @@ _arg_cache_out_array_setup (PyGIArgCache *arg_cache,
     }
 
     return TRUE;
-    /* arg_cache->cleanup = _pygi_cleanup_array; */
 }
 
 static inline void
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index e3516b4..a74cda8 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -310,5 +310,29 @@ _pygi_marshal_cleanup_out_array (PyGIInvokeState *state,
                                  gpointer         data,
                                  gboolean         was_processed)
 {
+    PyGISequenceCache *sequence_cache = (PyGISequenceCache *)arg_cache;
 
+    if (arg_cache->transfer == GI_TRANSFER_EVERYTHING) {
+        GArray *array_ = (GArray *) data;
+
+        if (sequence_cache->array_type == GI_ARRAY_TYPE_C) {
+            g_free (data);
+            return;
+        }
+
+        if (sequence_cache->item_cache->out_cleanup != NULL) {
+            int i;
+
+            PyGIMarshalCleanupFunc cleanup_func = sequence_cache->item_cache->out_cleanup;
+            for (i = 0; i < array_->len; i++) {
+                cleanup_func (state,
+                              sequence_cache->item_cache,
+                              g_array_index (array_, gpointer, i),
+                              was_processed);
+            }
+        }
+
+        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+            g_array_free (array_, TRUE);
+    }
 }
diff --git a/gi/pygi-marshal.c b/gi/pygi-marshal.c
index 1808f9f..d5e9b17 100644
--- a/gi/pygi-marshal.c
+++ b/gi/pygi-marshal.c
@@ -1590,6 +1590,7 @@ _pygi_marshal_out_array (PyGIInvokeState   *state,
     GArray *array_;
     PyObject *py_obj = NULL;
     PyGISequenceCache *seq_cache = (PyGISequenceCache *)arg_cache;
+    gsize processed_items = 0;
 
     array_ = arg->v_pointer;
 
@@ -1613,6 +1614,10 @@ _pygi_marshal_out_array (PyGIInvokeState   *state,
                               seq_cache->item_size);
         if (array_ == NULL) {
             PyErr_NoMemory ();
+
+            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+                g_free (arg->v_pointer);
+
             return NULL;
         }
 
@@ -1637,12 +1642,9 @@ _pygi_marshal_out_array (PyGIInvokeState   *state,
             PyGIArgCache *item_arg_cache;
 
             py_obj = PyList_New (array_->len);
-            if (py_obj == NULL) {
-                if (seq_cache->array_type == GI_ARRAY_TYPE_C)
-                    g_array_unref (array_);
+            if (py_obj == NULL)
+                goto err;
 
-                return NULL;
-            }
 
             item_arg_cache = seq_cache->item_cache;
             item_out_marshaller = item_arg_cache->out_marshaller;
@@ -1680,9 +1682,10 @@ _pygi_marshal_out_array (PyGIInvokeState   *state,
                     if (seq_cache->array_type == GI_ARRAY_TYPE_C)
                         g_array_unref (array_);
 
-                    return NULL;
+                    goto err;
                 }
                 PyList_SET_ITEM (py_obj, i, py_item);
+                processed_items++;
             }
         }
     }
@@ -1691,6 +1694,28 @@ _pygi_marshal_out_array (PyGIInvokeState   *state,
         g_array_free (array_, FALSE);
 
     return py_obj;
+
+err:
+    if (seq_cache->array_type == GI_ARRAY_TYPE_C) {
+        g_array_free (array_, arg_cache->transfer == GI_TRANSFER_EVERYTHING);
+    } else {
+        /* clean up unprocessed items */
+        if (seq_cache->item_cache->out_cleanup != NULL) {
+            int j;
+            PyGIMarshalCleanupFunc cleanup_func = seq_cache->item_cache->out_cleanup;
+            for (j = processed_items; j < array_->len; j++) {
+                cleanup_func (state,
+                              seq_cache->item_cache,
+                              g_array_index (array_, gpointer, j),
+                              FALSE);
+            }
+        }
+
+        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+            g_array_free (array_, TRUE);
+    }
+
+    return NULL;
 }
 
 PyObject *



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