[pygi] Refactor implementation of scope call to allow for multiple calls during lifetime of function invoca



commit d3b5fae9d609dbcd83deb0fa9102b24faf76787c
Author: Zach Goldberg <zach zachgoldberg com>
Date:   Tue Apr 20 22:43:20 2010 -0400

    Refactor implementation of scope call to allow for multiple calls during lifetime of function invocation.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=616343

 gi/pygi-closure.c        |   10 +++++-----
 gi/pygi-info.c           |    9 +++++++--
 tests/test_everything.py |    9 +++++++++
 3 files changed, 21 insertions(+), 7 deletions(-)
---
diff --git a/gi/pygi-closure.c b/gi/pygi-closure.c
index 98c758d..a47e675 100644
--- a/gi/pygi-closure.c
+++ b/gi/pygi-closure.c
@@ -133,13 +133,13 @@ end:
         Py_XDECREF(closure->user_data);
 
     /* Now that the closure has finished we can make a decision about how
-       to free it.  Scope call gets free'd now, scope notified will be freed
-       when the notify is called and we can free async anytime we want
-       once we return from this function */
+       to free it.  Scope call gets free'd at the end of wrap_g_function_info_invoke
+       scope notified will be freed,  when the notify is called and we can free async 
+       anytime we want as long as its after we return from this function (you can't free the closure
+       you are currently using!)
+    */
     switch (closure->scope) {
     case GI_SCOPE_TYPE_CALL:
-        _pygi_invoke_closure_free(closure);
-        break;
     case GI_SCOPE_TYPE_NOTIFIED:        
         break;
     case GI_SCOPE_TYPE_ASYNC:
diff --git a/gi/pygi-info.c b/gi/pygi-info.c
index 59c99fa..4f30fbf 100644
--- a/gi/pygi-info.c
+++ b/gi/pygi-info.c
@@ -506,8 +506,8 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
     guint8 callback_index;
     guint8 user_data_index;
     guint8 destroy_notify_index;
-    PyGICClosure *closure;
-
+    PyGICClosure *closure = NULL;
+    
     glong error_arg_pos;
 
     GIArgInfo **arg_infos;
@@ -1257,6 +1257,11 @@ _wrap_g_function_info_invoke (PyGIBaseInfo *self,
 out:
     g_base_info_unref((GIBaseInfo *)return_type_info);
 
+    if (closure != NULL) {
+        if (closure->scope == GI_SCOPE_TYPE_CALL) 
+            _pygi_invoke_closure_free(closure);
+    }
+
     for (i = 0; i < n_args; i++) {
         g_base_info_unref((GIBaseInfo *)arg_type_infos[i]);
         g_base_info_unref((GIBaseInfo *)arg_infos[i]);
diff --git a/tests/test_everything.py b/tests/test_everything.py
index 148b8af..ce5ca95 100644
--- a/tests/test_everything.py
+++ b/tests/test_everything.py
@@ -134,3 +134,12 @@ class TestCallbacks(unittest.TestCase):
         i = Everything.test_callback_thaw_async();
         self.assertEquals(44, i);
         self.assertTrue(TestCallbacks.called)
+
+    def testCallbackScopeCall(self):
+        TestCallbacks.called = 0
+        def callback():
+            TestCallbacks.called += 1
+            return 0
+
+        Everything.test_multi_callback(callback)
+        self.assertEquals(TestCallbacks.called, 2)



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