[pygobject/invoke-rewrite] [gi-invoke-ng] tweek cleanup routines



commit 4f615c6e300d6f2d7551b640efa301060206ab58
Author: John (J5) Palmieri <johnp redhat com>
Date:   Thu May 5 14:04:34 2011 -0400

    [gi-invoke-ng] tweek cleanup routines

 gi/pygi-cache.c           |    5 +++
 gi/pygi-marshal-cleanup.c |   87 ++++++++++++++++++++++++++++++++++-----------
 gi/pygi-marshal-cleanup.h |    6 ++--
 gi/pygi-marshal.c         |   11 +-----
 4 files changed, 76 insertions(+), 33 deletions(-)
---
diff --git a/gi/pygi-cache.c b/gi/pygi-cache.c
index f71ce02..20c6578 100644
--- a/gi/pygi-cache.c
+++ b/gi/pygi-cache.c
@@ -650,6 +650,9 @@ _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->cleanup = _pygi_marshal_cleanup_gvalue;
 }
 
 static inline void
@@ -667,6 +670,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;
 }
 
 static inline void
@@ -674,6 +678,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;
 }
 
 static inline void
diff --git a/gi/pygi-marshal-cleanup.c b/gi/pygi-marshal-cleanup.c
index f4b58ea..2a98b89 100644
--- a/gi/pygi-marshal-cleanup.c
+++ b/gi/pygi-marshal-cleanup.c
@@ -127,18 +127,6 @@ pygi_marshal_cleanup_args (PyGIInvokeState   *state,
     }
 }
 
- void 
- _pygi_marshal_cleanup_gvalue (PyGIInvokeState *state,
-                               PyGIArgCache    *arg_cache,
-                               gpointer         data)
-{
-    /*
-    if (arg_cache->direction == GI_DIRECTION_IN)
-        if (arg_cache->transfer == GI_TRANSFER_EVERYTHING)
-    g_slice_free (GValue, data);
-    */
-}
-
 void 
 _pygi_marshal_cleanup_closure_unref (PyGIInvokeState *state,
                                      PyGIArgCache    *arg_cache,
@@ -148,15 +136,6 @@ _pygi_marshal_cleanup_closure_unref (PyGIInvokeState *state,
 }
 
 void
-_pygi_marshal_cleanup_object_unref (PyGIInvokeState *state,
-                                    PyGIArgCache    *arg_cache,
-                                    gpointer         data)
-{
-    g_object_unref ( (GObject *)data);
-}
-
-
-void
 _pygi_marshal_cleanup_utf8 (PyGIInvokeState *state,
                             PyGIArgCache    *arg_cache,
                             gpointer         data)
@@ -190,3 +169,69 @@ _pygi_marshal_cleanup_utf8 (PyGIInvokeState *state,
             break;
      }
 }
+
+void
+_pygi_marshal_cleanup_object (PyGIInvokeState *state,
+                              PyGIArgCache    *arg_cache,
+                              gpointer         data)
+{
+    /* 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;
+     }
+}
+
+void 
+_pygi_marshal_cleanup_gvalue (PyGIInvokeState *state,
+                              PyGIArgCache    *arg_cache,
+                              gpointer         data)
+{
+    /* 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;
+     }
+}
diff --git a/gi/pygi-marshal-cleanup.h b/gi/pygi-marshal-cleanup.h
index acc9718..badc63c 100644
--- a/gi/pygi-marshal-cleanup.h
+++ b/gi/pygi-marshal-cleanup.h
@@ -39,9 +39,9 @@ void _pygi_marshal_cleanup_gvalue         (PyGIInvokeState *state,
 void _pygi_marshal_cleanup_closure_unref  (PyGIInvokeState *state,
                                            PyGIArgCache    *arg_cache,
                                            gpointer         data);
-void _pygi_marshal_cleanup_object_unref   (PyGIInvokeState *state,
-                                           PyGIArgCache    *arg_cache,
-                                           gpointer         data);
+void _pygi_marshal_cleanup_object   (PyGIInvokeState *state,
+                                     PyGIArgCache    *arg_cache,
+                                     gpointer         data);
 G_END_DECLS
 
 #endif /* __PYGI_MARSHAL_CLEANUP_H__ */
diff --git a/gi/pygi-marshal.c b/gi/pygi-marshal.c
index 64a494e..901446d 100644
--- a/gi/pygi-marshal.c
+++ b/gi/pygi-marshal.c
@@ -1219,16 +1219,9 @@ _pygi_marshal_in_interface_struct (PyGIInvokeState   *state,
 
         value = g_slice_new0 (GValue);
 
-        /* if already a gvalue, copy, else marshal into gvalue */
+        /* if already a gvalue, use that, else marshal into gvalue */
         if (object_type == G_TYPE_VALUE) {
-            /* src GValue's lifecycle is handled by Python
-             * so we have to copy it into the destination's
-             * GValue which is freed during the cleanup of
-             * invoke.
-             */
-            GValue *src = (GValue *)( (PyGObject *)py_arg)->obj;
-            g_value_init (value, G_VALUE_TYPE (src));
-            g_value_copy (src, value);
+            value = (GValue *)( (PyGObject *)py_arg)->obj;
         } else {
             g_value_init (value, object_type);
             if (pyg_value_from_pyobject (value, py_arg) < 0) {



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