[pygobject/invoke-rewrite] [gi-invoke-ng] revamp cleanup framework to be orthogonal to cache setup



commit dbbcf4a0e76fb572d85843ee31c3798df5cd5cc5
Author: John (J5) Palmieri <johnp redhat com>
Date:   Mon May 23 16:59:57 2011 -0400

    [gi-invoke-ng] revamp cleanup framework to be orthogonal to cache setup
    
    * cleanup now has symmetry with setup so there are now in and out cleanups
      for each type that needs to be cleaned up
    * no longer use state machine but instead call different cleanup functions at
      different stages of invoke, making it easier to understand what happens at
      each stage

 gi/pygi-cache.c               |   19 ++-
 gi/pygi-cache.h               |    7 +-
 gi/pygi-invoke-ng.c           |   10 +--
 gi/pygi-invoke-state-struct.h |    2 +
 gi/pygi-marshal-cleanup.c     |  301 ++++++++++++++++-------------------------
 gi/pygi-marshal-cleanup.h     |   45 ++++---
 gi/pygi-marshal.c             |   15 +-
 7 files changed, 174 insertions(+), 225 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 20c6578..45d17a7 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -467,7 +467,7 @@ _arg_cache_in_utf8_setup (PyGIArgCache *arg_cache,
                           GITransfer transfer)
 {
     arg_cache->in_marshaller = _pygi_marshal_in_utf8;
-    arg_cache->cleanup = _pygi_marshal_cleanup_utf8;
+    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_utf8;
 }
 
 static inline void
@@ -475,7 +475,7 @@ _arg_cache_out_utf8_setup (PyGIArgCache *arg_cache,
                            GITransfer transfer)
 {
     arg_cache->out_marshaller = _pygi_marshal_out_utf8;
-    arg_cache->cleanup = _pygi_marshal_cleanup_utf8;
+    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_utf8;
 }
 
 static inline void
@@ -483,7 +483,7 @@ _arg_cache_in_filename_setup (PyGIArgCache *arg_cache,
                               GITransfer transfer)
 {
     arg_cache->in_marshaller = _pygi_marshal_in_filename;
-    arg_cache->cleanup = _pygi_marshal_cleanup_utf8;
+    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_utf8;
 }
 
 static inline void
@@ -491,7 +491,7 @@ _arg_cache_out_filename_setup (PyGIArgCache *arg_cache,
                                GITransfer transfer)
 {
     arg_cache->out_marshaller = _pygi_marshal_out_filename;
-    arg_cache->cleanup = _pygi_marshal_cleanup_utf8;
+    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_utf8;
 }
 
 static inline gboolean
@@ -652,7 +652,9 @@ _arg_cache_in_interface_struct_setup (PyGIArgCache *arg_cache,
     arg_cache->in_marshaller = _pygi_marshal_in_interface_struct;
 
     if (iface_cache->g_type == G_TYPE_VALUE)
-        arg_cache->cleanup = _pygi_marshal_cleanup_gvalue;
+        arg_cache->in_cleanup = _pygi_marshal_cleanup_in_interface_struct_gvalue;
+    else if (iface_cache->is_foreign)
+        arg_cache->in_cleanup = _pygi_marshal_cleanup_in_interface_struct_foreign;
 }
 
 static inline void
@@ -663,6 +665,9 @@ _arg_cache_out_interface_struct_setup (PyGIArgCache *arg_cache,
     PyGIInterfaceCache *iface_cache = (PyGIInterfaceCache *)arg_cache;
     iface_cache->is_foreign = g_struct_info_is_foreign ( (GIStructInfo*)iface_info);
     arg_cache->out_marshaller = _pygi_marshal_out_interface_struct;
+
+    if (iface_cache->is_foreign)
+        arg_cache->in_cleanup = _pygi_marshal_cleanup_out_interface_struct_foreign;
 }
 
 static inline void
@@ -670,7 +675,7 @@ _arg_cache_in_interface_object_setup (PyGIArgCache *arg_cache,
                                       GITransfer transfer)
 {
     arg_cache->in_marshaller = _pygi_marshal_in_interface_object;
-    arg_cache->cleanup = _pygi_marshal_cleanup_object;
+    arg_cache->in_cleanup = _pygi_marshal_cleanup_in_interface_object;
 }
 
 static inline void
@@ -678,7 +683,7 @@ _arg_cache_out_interface_object_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
 {
     arg_cache->out_marshaller = _pygi_marshal_out_interface_object;
-    arg_cache->cleanup = _pygi_marshal_cleanup_object;
+    arg_cache->out_cleanup = _pygi_marshal_cleanup_out_interface_object;
 }
 
 static inline void
diff --git a/gi/pygi-cache.h b/gi/pygi-cache.h
index 64b5e19..046881d 100644
--- a/gi/pygi-cache.h
+++ b/gi/pygi-cache.h
@@ -46,7 +46,8 @@ typedef PyObject *(*PyGIMarshalOutFunc) (PyGIInvokeState   *state,
 
 typedef void (*PyGIMarshalCleanupFunc) (PyGIInvokeState *state,
                                         PyGIArgCache    *arg_cache,
-                                        gpointer         *data);
+                                        gpointer         data,
+                                        gboolean         was_processed);
 typedef enum {
   /* Not an AUX type */
   PYGI_AUX_TYPE_NONE   = 0,
@@ -72,7 +73,9 @@ struct _PyGIArgCache
     PyGIMarshalInFunc in_marshaller;
     PyGIMarshalOutFunc out_marshaller;
 
-    PyGIMarshalCleanupFunc cleanup;
+    PyGIMarshalCleanupFunc in_cleanup;
+    PyGIMarshalCleanupFunc out_cleanup;
+
     GDestroyNotify destroy_notify;
 
     gssize c_arg_index;
diff --git a/gi/pygi-invoke-ng.c b/gi/pygi-invoke-ng.c
index ea3e20b..da16755 100644
--- a/gi/pygi-invoke-ng.c
+++ b/gi/pygi-invoke-ng.c
@@ -74,7 +74,6 @@ _invoke_callable (PyGIInvokeState *state,
 
     if (state->error != NULL) {
         if (pyglib_error_check (&(state->error))) {
-            state->stage = PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED;
             /* even though we errored out, the call itself was successful,
                so we assume the call processed all of the parameters */
             pygi_marshal_cleanup_args_in_marshal_success (state, cache);
@@ -91,7 +90,6 @@ _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
                                         PyObject *py_args,
                                         PyObject *kwargs)
 {
-    state->stage = PYGI_INVOKE_STAGE_MARSHAL_IN_START;
     state->py_in_args = py_args;
     state->n_py_in_args = PySequence_Length (py_args);
 
@@ -109,6 +107,7 @@ _invoke_state_init_from_callable_cache (PyGIInvokeState *state,
                           "Constructors require the class to be passed in as an argument, "
                           "No arguments passed to the %s constructor.",
                           cache->name);
+
             return FALSE;
         }
 
@@ -200,8 +199,6 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache)
         PyGIArgCache *arg_cache = cache->args_cache[i];
         PyObject *py_arg = NULL;
 
-        state->current_arg = i;
-        state->stage = PYGI_INVOKE_STAGE_MARSHAL_IN_START;
         switch (arg_cache->direction) {
             case GI_DIRECTION_IN:
                 state->args[i] = &(state->in_args[in_count]);
@@ -334,8 +331,6 @@ _invoke_marshal_out_args (PyGIInvokeState *state, PyGICallableCache *cache)
     int total_out_args = cache->n_out_args;
     gboolean has_return = FALSE;
 
-    state->current_arg = 0;
-
     if (cache->return_cache) {
         state->stage = PYGI_INVOKE_STAGE_MARSHAL_RETURN_START;
         if (cache->is_constructor) {
@@ -414,9 +409,6 @@ _invoke_marshal_out_args (PyGIInvokeState *state, PyGICallableCache *cache)
                 return NULL;
             }
 
-            state->current_arg++;
-            state->stage = PYGI_INVOKE_STAGE_MARSHAL_OUT_IDLE;
-
             PyTuple_SET_ITEM (py_out, py_arg_index, py_obj);
             cache_item = cache_item->next;
         }
diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h
index 3e463f8..40c796c 100644
--- a/gi/pygi-invoke-state-struct.h
+++ b/gi/pygi-invoke-state-struct.h
@@ -50,6 +50,8 @@ typedef struct _PyGIInvokeState
     GIArgument return_arg;
 
     GError *error;
+
+    gboolean failed;
 } PyGIInvokeState;
 
 G_END_DECLS
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index 88ed2ec..d4d2186 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -77,14 +77,45 @@ void
 pygi_marshal_cleanup_args_in_marshal_success (PyGIInvokeState   *state,
                                               PyGICallableCache *cache)
 {
+    int i;
 
+    /* For in success, call cleanup for all GI_DIRECTION_IN values only. */
+    for (i = 0; i < cache->n_args; i++) {
+        PyGIArgCache *arg_cache = cache->args_cache[i];
+        PyGIMarshalCleanupFunc cleanup_func = arg_cache->in_cleanup;
+
+        if (cleanup_func && arg_cache->direction == GI_DIRECTION_IN)
+            cleanup_func (state, arg_cache, state->args[i]->v_pointer, TRUE);
+    }
 }
 
 void
-pygi_marshal_cleanup_args_invoke_success (PyGIInvokeState   *state,
-                                          PyGICallableCache *cache)
+pygi_marshal_cleanup_args_out_marshal_success (PyGIInvokeState   *state,
+                                               PyGICallableCache *cache)
 {
+    /* clean up the return if available */
+    if (cache->return_cache != NULL) {
+        PyGIMarshalCleanupFunc cleanup_func = cache->return_cache->out_cleanup;
+        if (cleanup_func)
+            cleanup_func (state,
+                          cache->return_cache,
+                          state->return_arg.v_pointer,
+                          TRUE);
+    }
 
+    /* Now clean up args */
+    GSList *cache_item = cache->out_args;
+    while (cache_item) {
+        PyGIArgCache *arg_cache = (PyGIArgCache *) cache_item->data;
+        PyGIMarshalCleanupFunc cleanup_func = arg_cache->out_cleanup;
+        if (cleanup_func != NULL)
+            cleanup_func (state,
+                          arg_cache,
+                          state->args[arg_cache->c_arg_index]->v_pointer,
+                          TRUE);
+
+        cache_item = cache_item->next;
+    }
 }
 
 void
@@ -92,14 +123,14 @@ pygi_marshal_cleanup_args_in_parameter_fail (PyGIInvokeState   *state,
                                              PyGICallableCache *cache,
                                              gssize failed_arg_index)
 {
-
+    state->failed = TRUE;
 }
 
 void
 pygi_marshal_cleanup_args_return_fail (PyGIInvokeState   *state,
                                        PyGICallableCache *cache)
 {
-
+    state->failed = TRUE;
 }
 
 void
@@ -107,203 +138,107 @@ pygi_marshal_cleanup_args_out_parameter_fail (PyGIInvokeState   *state,
                                               PyGICallableCache *cache,
                                               gssize failed_out_arg_index)
 {
+    state->failed = TRUE;
+}
 
+void 
+_pygi_marshal_cleanup_closure_unref (PyGIInvokeState *state,
+                                     PyGIArgCache    *arg_cache,
+                                     gpointer         data,
+                                     gboolean         was_processed)
+{
+    g_closure_unref ( (GClosure *)data);
 }
 
 void
-pygi_marshal_cleanup_args (PyGIInvokeState   *state,
-                           PyGICallableCache *cache,
-                           gboolean invoke_failure)
+_pygi_marshal_cleanup_in_utf8 (PyGIInvokeState *state,
+                               PyGIArgCache    *arg_cache,
+                               gpointer         data,
+                               gboolean         was_processed)
 {
-    switch (state->stage) {
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_IDLE:
-            /* current_arg has been marshalled so increment to start with
-               next arg */
-            state->current_arg++;
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_START:
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED:
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE:
-        {
-            gsize i;
-            /* we have not yet invoked so we only need to clean up 
-               the in args and out caller allocates */
-
-            for (i = 0; i < state->current_arg; i++) {
-                PyGIArgCache *arg_cache = cache->args_cache[i];
-                PyGIMarshalCleanupFunc cleanup_func = arg_cache->cleanup;
-
-                /* FIXME: handle caller allocates */
-                if (invoke_failure && 
-                      arg_cache->direction == GI_DIRECTION_OUT &&
-                        arg_cache->is_caller_allocates) {
-                    _cleanup_caller_allocates (state,
-                                               (PyGIInterfaceCache *) arg_cache,
-                                               state->args[i]->v_pointer);
-                } else if (cleanup_func != NULL  &&
-                             arg_cache->direction != GI_DIRECTION_OUT) {
-                    cleanup_func (state, arg_cache, state->args[i]->v_pointer);
-                }
-            }
-            break;
-        }
-
-        case PYGI_INVOKE_STAGE_DONE:
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_START:
-            /* clean up the return if not marshalled */
-            if (cache->return_cache != NULL) {
-                PyGIMarshalCleanupFunc cleanup_func =
-                    cache->return_cache->cleanup;
-
-                if (cleanup_func)
-                    cleanup_func (state,
-                                  cache->return_cache,
-                                  state->return_arg.v_pointer);
-            }
-
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_IDLE:
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_DONE:
-        {
-            /* Cleanup caller allocate args and any unmarshalled arg */
-            GSList *cache_item = cache->out_args;
-            gsize arg_index = 0;
-
-            if (state->stage == PYGI_INVOKE_STAGE_MARSHAL_OUT_START) {
-                /* we have not yet marshalled so decrement to end with
-                   previous arg */
-                state->current_arg--;
-            }
-
-            /* clean up the args */
-            while (cache_item != NULL) {
-                PyGIArgCache *arg_cache = (PyGIArgCache *) cache_item->data;
-                PyGIMarshalCleanupFunc cleanup_func = arg_cache->cleanup;
-
-                if (arg_index > state->current_arg) {
-                    if (cleanup_func != NULL)
-                        cleanup_func (state,
-                                      arg_cache,
-                                      state->args[arg_cache->c_arg_index]->v_pointer);
-
-                    if (arg_cache->is_caller_allocates)
-                        _cleanup_caller_allocates (state,
-                                                   (PyGIInterfaceCache *) arg_cache,
-                                                   state->args[arg_cache->c_arg_index]->v_pointer);
-                }
-
-                arg_index++;
-                cache_item = cache_item->next;
-            }
-            break;
-        }
-    }
+    /* We strdup strings so always free if we have processed this
+       parameter for input */
+    if (was_processed)
+        g_free (data);
 }
 
-void 
-_pygi_marshal_cleanup_closure_unref (PyGIInvokeState *state,
-                                     PyGIArgCache    *arg_cache,
-                                     gpointer         data)
+void
+_pygi_marshal_cleanup_out_utf8 (PyGIInvokeState *state,
+                                PyGIArgCache    *arg_cache,
+                                gpointer         data,
+                                gboolean         was_processed)
 {
-    g_closure_unref ( (GClosure *)data);
+    /* Python copies the string so we need to free it
+       if the interface is transfering ownership, 
+       whether or not it has been processed yet */
+    if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+        g_free (data);
 }
 
 void
-_pygi_marshal_cleanup_utf8 (PyGIInvokeState *state,
-                            PyGIArgCache    *arg_cache,
-                            gpointer         data)
+_pygi_marshal_cleanup_in_interface_object (PyGIInvokeState *state,
+                                           PyGIArgCache    *arg_cache,
+                                           gpointer         data,
+                                           gboolean         was_processed)
 {
-    /* For in or inout values before invoke we need to free this,
-     * but after invoke we we free only if transfer == GI_TRANSFER_NOTHING
-     * and this is not an inout value
-     *
-     * For out and inout values before invoke we do nothing but after invoke
-     * we free if transfer == GI_TRANSFER_EVERYTHING
-     */
-    switch (state->stage) {
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_IDLE:
-            g_free (data);
-            break;
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED:
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE:
-            if (arg_cache->transfer == GI_TRANSFER_NOTHING &&
-                  arg_cache->direction == GI_DIRECTION_IN)
-                g_free (data);
-            break;
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_DONE:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_IDLE:
-            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
-                g_free (data);
-            break;
-        default:
-            break;
-     }
+    /* If we processed the parameter but fail before invoking the method,
+       we need to remove the ref we added */
+    if (was_processed && state->failed && data != NULL &&
+            arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+        g_object_unref (G_OBJECT(data));
 }
 
 void
-_pygi_marshal_cleanup_object (PyGIInvokeState *state,
-                              PyGIArgCache    *arg_cache,
-                              gpointer         data)
+_pygi_marshal_cleanup_out_interface_object (PyGIInvokeState *state,
+                                            PyGIArgCache    *arg_cache,
+                                            gpointer         data,
+                                            gboolean         was_processed)
 {
-    /* For in or inout values before invoke we need to unref
-     * only if transfer == GI_TRANSFER_EVERYTHING
-     *
-     * For out and inout values before invoke we do nothing but after invoke
-     * we unref if transfer == GI_TRANSFER_EVERYTHING
-     */
-    switch (state->stage) {
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_IDLE:
-            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING &&
-                  arg_cache->direction == GI_DIRECTION_IN)
-                g_object_unref (G_OBJECT(data));
-            break;
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED:
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE:
-            break;
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_DONE:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_IDLE:
-            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
-                g_object_unref (G_OBJECT(data));
-            break;
-        default:
-            break;
-     }
+    /* If we error out and the object is not marshalled into a PyGObject
+       we must take care of removing the ref */
+    if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+        g_object_unref (G_OBJECT(data));
 }
 
 void 
-_pygi_marshal_cleanup_gvalue (PyGIInvokeState *state,
-                              PyGIArgCache    *arg_cache,
-                              gpointer         data)
+_pygi_marshal_cleanup_in_interface_struct_gvalue (PyGIInvokeState *state,
+                                                  PyGIArgCache    *arg_cache,
+                                                  gpointer         data,
+                                                  gboolean         was_processed)
+{
+    if (was_processed) {
+        PyObject *py_arg = PyTuple_GET_ITEM (state->py_in_args,
+                                             arg_cache->py_arg_index);
+        GType py_object_type =
+            pyg_type_from_object_strict ( (PyObject *) py_arg->ob_type, FALSE);
+
+        if (py_object_type != G_TYPE_VALUE) {
+            g_value_unset ((GValue *) data);
+            g_slice_free (GValue, data);
+        }
+    }
+}
+
+void
+_pygi_marshal_cleanup_in_interface_struct_foreign (PyGIInvokeState *state,
+                                                   PyGIArgCache    *arg_cache,
+                                                   gpointer         data,
+                                                   gboolean         was_processed)
+{
+    if (state->failed && was_processed)
+        pygi_struct_foreign_release (
+            ( (PyGIInterfaceCache *)arg_cache)->interface_info,
+            data);
+}
+
+void
+_pygi_marshal_cleanup_out_interface_struct_foreign (PyGIInvokeState *state,
+                                                    PyGIArgCache    *arg_cache,
+                                                    gpointer         data,
+                                                    gboolean         was_processed)
 {
-    /* For in or inout values before invoke we need to unset and slice_free
-     * After invoke we unset and free if transfer == GI_TRANSFER_NOTHING
-     *
-     * For out values before invoke we do nothing but after invoke
-     * we unset if transfer == GI_TRANSFER_EVERYTHING
-     *
-     */
-    switch (state->stage) {
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_IN_IDLE:
-                g_value_unset ((GValue *) data);
-                g_slice_free (GValue, data);
-            break;
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED:
-        case PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE:
-            break;
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_RETURN_DONE:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_START:
-        case PYGI_INVOKE_STAGE_MARSHAL_OUT_IDLE:
-            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
-                g_value_unset ((GValue *) data);
-            break;
-        default:
-            break;
-     }
+    if (!was_processed && arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+        pygi_struct_foreign_release ( 
+            ( (PyGIInterfaceCache *)arg_cache)->interface_info,
+            data);
 }
diff --git a/gi/pygi-marshal-cleanup.h b/gi/pygi-marshal-cleanup.h
index 55624be..de1be57 100644
--- a/gi/pygi-marshal-cleanup.h
+++ b/gi/pygi-marshal-cleanup.h
@@ -40,22 +40,35 @@ void pygi_marshal_cleanup_args_out_parameter_fail  (PyGIInvokeState   *state,
                                                     PyGICallableCache *cache,
                                                     gssize failed_out_arg_index);
 
-void pygi_marshal_cleanup_args            (PyGIInvokeState   *state,
-                                           PyGICallableCache *cache,
-                                           gboolean           invoke_failure);
-
-void _pygi_marshal_cleanup_utf8           (PyGIInvokeState *state,
-                                           PyGIArgCache    *arg_cache,
-                                           gpointer         data);
-void _pygi_marshal_cleanup_gvalue         (PyGIInvokeState *state,
-                                           PyGIArgCache    *arg_cache,
-                                           gpointer         data);
-void _pygi_marshal_cleanup_closure_unref  (PyGIInvokeState *state,
-                                           PyGIArgCache    *arg_cache,
-                                           gpointer         data);
-void _pygi_marshal_cleanup_object   (PyGIInvokeState *state,
-                                     PyGIArgCache    *arg_cache,
-                                     gpointer         data);
+void _pygi_marshal_cleanup_in_utf8                      (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+void _pygi_marshal_cleanup_out_utf8                     (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+void _pygi_marshal_cleanup_in_interface_struct_gvalue   (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+void _pygi_marshal_cleanup_in_interface_struct_foreign  (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+void _pygi_marshal_cleanup_out_interface_struct_foreign (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+void _pygi_marshal_cleanup_in_interface_object          (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+void _pygi_marshal_cleanup_out_interface_object         (PyGIInvokeState *state,
+                                                         PyGIArgCache    *arg_cache,
+                                                         gpointer         data,
+                                                         gboolean         was_processed);
+
 G_END_DECLS
 
 #endif /* __PYGI_MARSHAL_CLEANUP_H__ */
diff --git a/gi/pygi-marshal.c b/gi/pygi-marshal.c
index 901446d..f6c84fa 100644
--- a/gi/pygi-marshal.c
+++ b/gi/pygi-marshal.c
@@ -722,8 +722,8 @@ _pygi_marshal_in_array (PyGIInvokeState   *state,
         g_array_insert_val (array_, i, item);
         continue;
 err:
-        if (sequence_cache->item_cache->cleanup != NULL) {
-            GDestroyNotify cleanup = sequence_cache->item_cache->cleanup;
+        if (sequence_cache->item_cache->in_cleanup != NULL) {
+            GDestroyNotify cleanup = sequence_cache->item_cache->in_cleanup;
             /*for(j = 0; j < i; j++)
                 cleanup((gpointer)(array_->data[j]));*/
         }
@@ -815,8 +815,8 @@ _pygi_marshal_in_glist (PyGIInvokeState   *state,
         list_ = g_list_append (list_, item.v_pointer);
         continue;
 err:
-        if (sequence_cache->item_cache->cleanup != NULL) {
-            GDestroyNotify cleanup = sequence_cache->item_cache->cleanup;
+        if (sequence_cache->item_cache->in_cleanup != NULL) {
+            GDestroyNotify cleanup = sequence_cache->item_cache->in_cleanup;
         }
 
         g_list_free (list_);
@@ -881,8 +881,8 @@ _pygi_marshal_in_gslist (PyGIInvokeState   *state,
         list_ = g_slist_append (list_, item.v_pointer);
         continue;
 err:
-        if (sequence_cache->item_cache->cleanup != NULL) {
-            GDestroyNotify cleanup = sequence_cache->item_cache->cleanup;
+        if (sequence_cache->item_cache->in_cleanup != NULL) {
+            GDestroyNotify cleanup = sequence_cache->item_cache->in_cleanup;
         }
 
         g_slist_free (list_);
@@ -1217,12 +1217,11 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState   *state,
             return FALSE;
         }
 
-        value = g_slice_new0 (GValue);
-
         /* if already a gvalue, use that, else marshal into gvalue */
         if (object_type == G_TYPE_VALUE) {
             value = (GValue *)( (PyGObject *)py_arg)->obj;
         } else {
+            value = g_slice_new0 (GValue);
             g_value_init (value, object_type);
             if (pyg_value_from_pyobject (value, py_arg) < 0) {
                 g_slice_free (GValue, value);



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