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



commit be27b9e6d1b7cb590dcda6be6621d707887c87cb
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     |   65 +++++++++++++++++++++++++++++++++---
 tests/Makefile.am                 |    1 +
 tests/asynchronous/bug783543.vala |   15 ++++++++
 3 files changed, 75 insertions(+), 6 deletions(-)
---
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 002c488..dd8e916 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -33,6 +33,7 @@ public class Vala.GAsyncModule : GtkModule {
 
                data.add_field ("GTask*", "_async_result");
                if (!context.require_glib_version (2, 44)) {
+                       data.add_field ("GAsyncReadyCallback", "_callback_");
                        data.add_field ("gboolean", "_task_complete_");
                }
 
@@ -160,9 +161,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, 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);
@@ -211,6 +261,10 @@ public class Vala.GAsyncModule : GtkModule {
                ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
                ccode.add_assignment (data_var, dataalloc);
 
+               if (!context.require_glib_version (2, 44)) {
+                       ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, "_callback_"), new 
CCodeConstant ("_callback_"));
+               }
+
                var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_task_new"));
 
                var t = m.parent_symbol as TypeSymbol;
@@ -239,7 +293,11 @@ public class Vala.GAsyncModule : GtkModule {
                        create_result.add_argument (new CCodeIdentifier (get_variable_cname 
(cancellable_param.name)));
                }
 
-               create_result.add_argument (new CCodeIdentifier ("_callback_"));
+               if (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_"));
 
                ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), 
create_result);
@@ -584,11 +642,6 @@ public class Vala.GAsyncModule : GtkModule {
                        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"));
-               }
-
                emit_context.push_symbol (m);
                foreach (Parameter param in m.get_parameters ()) {
                        if (param.direction != ParameterDirection.IN) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 765d26b..0611849 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -266,6 +266,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]