[vala/0.36: 25/212] codegen: Make the task_complete flag for < 2.44 more similar to >= 2.44



commit f1a4bc6737a2fc7c3c8de56da955331054cab5a1
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jun 12 17:19:05 2017 +0200

    codegen: Make the task_complete flag for < 2.44 more similar to >= 2.44
    
    According to the g_task_get_completed() docs (which we rely on for
    glib >= 2.44 targets): "This changes from FALSE to TRUE after the task's
    callback is invoked, and will return FALSE from inside the callback".
    
    So to make the code paths most similar to >= 2.44 (when
    g_task_get_completed is available), wrap the GAsyncReadyCallback with
    one of our own, that just invokes the nested callback (if any) and turns
    on the flag.
    
    Also remove the code turning on the flag on finish(), it's superfluous
    now and there are no guarantees that it will be invoked.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=783543

 codegen/valagasyncmodule.vala     |   64 +++++++++++++++++++++++++++++++++---
 tests/Makefile.am                 |    1 +
 tests/asynchronous/bug783543.vala |   15 +++++++++
 3 files changed, 74 insertions(+), 6 deletions(-)
---
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index a077b4a..1cc074b 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -34,6 +34,7 @@ public class Vala.GAsyncModule : GtkModule {
                if (context.require_glib_version (2, 36)) {
                        data.add_field ("GTask*", "_async_result");
                        if (!context.require_glib_version (2, 44)) {
+                               data.add_field ("GAsyncReadyCallback", "_callback_");
                                data.add_field ("gboolean", "_task_complete_");
                        }
                } else {
@@ -164,9 +165,58 @@ public class Vala.GAsyncModule : GtkModule {
                return freefunc;
        }
 
+       void generate_async_ready_callback_wrapper (Method m, string function_name) {
+               var function = new CCodeFunction (function_name, "void");
+               function.modifiers = CCodeModifiers.STATIC;
+
+               function.add_parameter (new CCodeParameter ("*source_object", "GObject"));
+               function.add_parameter (new CCodeParameter ("*res", "GAsyncResult"));
+               function.add_parameter (new CCodeParameter ("*user_data", "void"));
+
+               push_function (function);
+
+               // Set _task_complete_ to false after calling back to the real func
+               var async_result_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_TASK"));
+               async_result_cast.add_argument (new CCodeIdentifier ("res"));
+
+               var dataname = Symbol.lower_case_to_camel_case (get_ccode_name (m)) + "Data";
+               ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_task_data_"));
+
+               var get_data_call = new CCodeFunctionCall (new CCodeIdentifier ("g_task_get_task_data"));
+               get_data_call.add_argument (async_result_cast);
+
+               var data_var = new CCodeIdentifier ("_task_data_");
+               ccode.add_assignment (data_var, get_data_call);
+
+               var task_inner_callback = new CCodeMemberAccess.pointer (data_var, "_callback_");
+               var callback_is_nonnull = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, 
task_inner_callback, new CCodeConstant ("NULL"));
+
+               ccode.open_if (callback_is_nonnull);
+               var nested_callback = new CCodeFunctionCall (task_inner_callback);
+               nested_callback.add_argument (new CCodeIdentifier ("source_object"));
+               nested_callback.add_argument (new CCodeIdentifier ("res"));
+               nested_callback.add_argument (new CCodeIdentifier ("user_data"));
+               ccode.add_expression (nested_callback);
+               ccode.close ();
+
+               ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, "_task_complete_"), new 
CCodeConstant ("TRUE"));
+
+               pop_function ();
+
+               cfile.add_function_declaration (function);
+               cfile.add_function (function);
+       }
+
        void generate_async_function (Method m) {
                push_context (new EmitContext ());
 
+               string? callback_wrapper = null;
+
+               if (context.require_glib_version (2, 36) && !context.require_glib_version (2, 44)) {
+                       callback_wrapper = get_ccode_real_name (m) + "_async_ready_wrapper";
+                       generate_async_ready_callback_wrapper (m, callback_wrapper);
+               }
+
                var dataname = Symbol.lower_case_to_camel_case (get_ccode_name (m)) + "Data";
                var asyncfunc = new CCodeFunction (get_ccode_real_name (m), "void");
                var cparam_map = new HashMap<int,CCodeParameter> (direct_hash, direct_equal);
@@ -218,6 +268,9 @@ public class Vala.GAsyncModule : GtkModule {
                CCodeFunctionCall? create_result = null;
 
                if (context.require_glib_version (2, 36)) {
+                       if (!context.require_glib_version (2, 44)) {
+                               ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, "_callback_"), 
new CCodeConstant ("_callback_"));
+                       }
                        create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_task_new"));
                } else {
                        create_result = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_new"));
@@ -251,7 +304,11 @@ public class Vala.GAsyncModule : GtkModule {
                        }
                }
 
-               create_result.add_argument (new CCodeIdentifier ("_callback_"));
+               if (!context.require_glib_version (2, 36) || context.require_glib_version (2, 44)) {
+                       create_result.add_argument (new CCodeIdentifier ("_callback_"));
+               } else {
+                       create_result.add_argument (new CCodeIdentifier (callback_wrapper));
+               }
                create_result.add_argument (new CCodeIdentifier ("_user_data_"));
 
                if (!context.require_glib_version (2, 36)) {
@@ -606,11 +663,6 @@ public class Vala.GAsyncModule : GtkModule {
                                return_default_value (return_type);
                                ccode.close ();
                        }
-
-                       if (!context.require_glib_version (2, 44)) {
-                               var task_completed_var = new CCodeMemberAccess.pointer (data_var, 
"_task_complete_");
-                               ccode.add_assignment (task_completed_var, new CCodeConstant ("TRUE"));
-                       }
                } else {
                        var simple_async_result_cast = new CCodeFunctionCall (new CCodeIdentifier 
("G_SIMPLE_ASYNC_RESULT"));
                        simple_async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6036da7..d279144 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -262,6 +262,7 @@ TESTS = \
        asynchronous/bug742621.vala \
        asynchronous/bug762819.vala \
        asynchronous/bug777242.vala \
+       asynchronous/bug783543.vala \
        asynchronous/closures.vala \
        asynchronous/generator.vala \
        asynchronous/yield.vala \
diff --git a/tests/asynchronous/bug783543.vala b/tests/asynchronous/bug783543.vala
new file mode 100644
index 0000000..08148f4
--- /dev/null
+++ b/tests/asynchronous/bug783543.vala
@@ -0,0 +1,15 @@
+class Foo : Object {
+       public async void bar () {
+               Idle.add (bar.callback);
+               yield;
+       }
+}
+
+void main () {
+       var loop = new MainLoop ();
+       var foo = new Foo ();
+       foo.bar.begin (() => {
+               loop.quit ();
+       });
+       loop.run ();
+}


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