[pygobject/invoke-rewrite] [gi-invoke-ng] refactor the cleanup code and add utf8 cleanup as initial test



commit cdbf57f3b1f041a06cf545a5557424f701ed1ec7
Author: John (J5) Palmieri <johnp redhat com>
Date:   Thu Apr 28 19:16:02 2011 -0400

    [gi-invoke-ng] refactor the cleanup code and add utf8 cleanup as initial test

 gi/pygi-cache.c               |   15 +----------
 gi/pygi-invoke-ng.c           |    8 ++----
 gi/pygi-invoke-state-struct.h |    2 +
 gi/pygi-marshal-cleanup.c     |   51 ++++++++++++++++++++++++++++++++++++++++-
 gi/pygi-marshal-cleanup.h     |    3 ++
 5 files changed, 60 insertions(+), 19 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index 7a38db5..9b8b5a5 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -467,6 +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;
 }
 
 static inline void
@@ -474,6 +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;
 }
 
 static inline void
@@ -646,12 +648,6 @@ _arg_cache_in_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->in_marshaller = _pygi_marshal_in_interface_struct;
-    if (iface_cache->g_type == G_TYPE_VALUE && 
-            arg_cache->transfer == GI_TRANSFER_NOTHING &&
-                arg_cache->direction == GI_DIRECTION_IN)
-        arg_cache->cleanup = _pygi_marshal_cleanup_gvalue;
-    if (iface_cache->g_type == G_TYPE_CLOSURE)
-        arg_cache->cleanup = _pygi_marshal_cleanup_closure_unref;
 }
 
 static inline void
@@ -662,11 +658,6 @@ _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->g_type == G_TYPE_VALUE && 
-            arg_cache->transfer != GI_TRANSFER_NOTHING &&
-                arg_cache->direction == GI_DIRECTION_OUT)
-        arg_cache->cleanup = _pygi_marshal_cleanup_gvalue;
 }
 
 static inline void
@@ -681,8 +672,6 @@ _arg_cache_out_interface_object_setup (PyGIArgCache *arg_cache,
                                        GITransfer transfer)
 {
     arg_cache->out_marshaller = _pygi_marshal_out_interface_object;
-    if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
-        arg_cache->cleanup = _pygi_marshal_cleanup_object_unref;
 }
 
 static inline void
diff --git a/gi/pygi-invoke-ng.c b/gi/pygi-invoke-ng.c
index dc5bd70..51e6f6e 100644
--- a/gi/pygi-invoke-ng.c
+++ b/gi/pygi-invoke-ng.c
@@ -62,15 +62,12 @@ _invoke_callable (PyGIInvokeState *state,
         g_assert (error != NULL);
         pyglib_error_check (&error);
 
-        /* TODO: release input arguments. */
-
         return FALSE;
     }
 
     if (state->error != NULL) {
         if (pyglib_error_check (&(state->error))) {
-            /* TODO: release input arguments. */
-
+            state->stage = PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED;
             return FALSE;
         }
     }
@@ -193,7 +190,7 @@ _invoke_marshal_in_args (PyGIInvokeState *state, PyGICallableCache *cache)
         PyGIArgCache *arg_cache = cache->args_cache[i];
         PyObject *py_arg = NULL;
 
-        state->current_arg = in_count;
+        state->current_arg = i;
         state->stage = PYGI_INVOKE_STAGE_MARSHAL_IN_START;
         switch (arg_cache->direction) {
             case GI_DIRECTION_IN:
@@ -406,6 +403,7 @@ _wrap_g_callable_info_invoke (PyGIBaseInfo *self,
     if (!_invoke_callable (&state, self->cache, self->info))
         goto err;
 
+    state.stage = PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE;
     pygi_marshal_cleanup_args (&state, self->cache);
 
     ret = _invoke_marshal_out_args (&state, self->cache);
diff --git a/gi/pygi-invoke-state-struct.h b/gi/pygi-invoke-state-struct.h
index 0643960..3e463f8 100644
--- a/gi/pygi-invoke-state-struct.h
+++ b/gi/pygi-invoke-state-struct.h
@@ -10,6 +10,8 @@ G_BEGIN_DECLS
 typedef enum {
     PYGI_INVOKE_STAGE_MARSHAL_IN_START,
     PYGI_INVOKE_STAGE_MARSHAL_IN_IDLE,
+    PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED,
+    PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE,
     PYGI_INVOKE_STAGE_MARSHAL_RETURN_START,
     PYGI_INVOKE_STAGE_MARSHAL_RETURN_DONE,
     PYGI_INVOKE_STAGE_MARSHAL_OUT_START,
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index aaab7b3..56dcccf 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -32,10 +32,24 @@ pygi_marshal_cleanup_args (PyGIInvokeState   *state,
                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 */
+               the in args and out caller allocates */
 
+            /* FIXME: handle caller allocates */
+            for (i = 0; i < state->current_arg; i++) {
+                PyGIArgCache *arg_cache = cache->args_cache[i];
+                PyGIMarshalCleanupFunc cleanup_func = arg_cache->cleanup;
+                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_MARSHAL_OUT_START:
             /* we have not yet marshalled so decrement to end with previous
                arg */
@@ -79,3 +93,38 @@ _pygi_marshal_cleanup_object_unref (PyGIInvokeState *state,
     g_object_unref ( (GObject *)data);
 }
 
+
+void
+_pygi_marshal_cleanup_utf8 (PyGIInvokeState *state,
+                            PyGIArgCache    *arg_cache,
+                            gpointer         data)
+{
+    /* 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) {
+        PYGI_INVOKE_STAGE_MARSHAL_IN_START:
+        PYGI_INVOKE_STAGE_MARSHAL_IN_IDLE:
+            g_free (data);
+            break;
+        PYGI_INVOKE_STAGE_NATIVE_INVOKE_FAILED:
+        PYGI_INVOKE_STAGE_NATIVE_INVOKE_DONE:
+            if (arg_cache->transfer == GI_TRANSFER_NOTHING &&
+                  arg_cache->direction == GI_DIRECTION_IN)
+                g_free (data);
+            break;
+        PYGI_INVOKE_STAGE_MARSHAL_RETURN_START:
+        PYGI_INVOKE_STAGE_MARSHAL_RETURN_DONE:
+        PYGI_INVOKE_STAGE_MARSHAL_OUT_START:
+        PYGI_INVOKE_STAGE_MARSHAL_OUT_IDLE:
+            if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
+                g_free (data);
+            break;
+        default:
+            break;
+     }
+}
diff --git a/gi/pygi-marshal-cleanup.h b/gi/pygi-marshal-cleanup.h
index dc5d66c..60114db 100644
--- a/gi/pygi-marshal-cleanup.h
+++ b/gi/pygi-marshal-cleanup.h
@@ -26,6 +26,9 @@
 
 G_BEGIN_DECLS
 
+void _pygi_marshal_cleanup_utf8           (PyGIInvokeState *state,
+                                           PyGIArgCache    *arg_cache,
+                                           gpointer         data);
 void pygi_marshal_cleanup_args            (PyGIInvokeState   *state,
                                            PyGICallableCache *cache);
 



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