[vala/staging: 1/4] codegen: Use GTask instead of GSimpleAsyncResult if 2.36 target is selected



commit 7fdc51050a574341fac66e20f5d0edc6fd16eb07
Author: Carlos Garnacho <carlosg gnome org>
Date:   Wed Mar 23 15:04:37 2016 +0100

    codegen: Use GTask instead of GSimpleAsyncResult if 2.36 target is selected
    
    GTask brings some differences compared to GSimpleAsyncResult. Most namely,
    g_task_return*() operations perform at once the async result data asignment
    and the caller's main context activation. This is something that has to be
    done exactly once, so the code flow has slight changes to ensure that.
    
    Also, the async operation data used to be attached early through
    g_simple_async_result_set_op_res_gpointer, only to be maybe replaced by
    the real return data. If GTask is being used, we set this data through
    g_task_set_task_data().
    
    https://bugzilla.gnome.org/show_bug.cgi?id=763345

 codegen/valaccodemethodmodule.vala |   40 ++++++----
 codegen/valagasyncmodule.vala      |  151 ++++++++++++++++++++++++++++--------
 codegen/valagdbusclientmodule.vala |   43 ++++++++---
 3 files changed, 173 insertions(+), 61 deletions(-)
---
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 19f507b..fc3ef34 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -124,24 +124,32 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
        }
 
        public void complete_async () {
-               var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_");
-               var zero = new CCodeConstant ("0");
-               var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, zero);
-               ccode.open_if (state_is_zero);
-
                var async_result_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), 
"_async_result");
 
-               var idle_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_complete_in_idle"));
-               idle_call.add_argument (async_result_expr);
-               ccode.add_expression (idle_call);
+               if (context.require_glib_version (2, 36)) {
+                       var finish_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_task_return_pointer"));
+                       finish_call.add_argument (async_result_expr);
+                       finish_call.add_argument (new CCodeIdentifier ("_data_"));
+                       finish_call.add_argument (new CCodeConstant ("NULL"));
+                       ccode.add_expression (finish_call);
+               } else {
+                       var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_");
+                       var zero = new CCodeConstant ("0");
+                       var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, 
zero);
+                       ccode.open_if (state_is_zero);
+
+                       var idle_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_complete_in_idle"));
+                       idle_call.add_argument (async_result_expr);
+                       ccode.add_expression (idle_call);
 
-               ccode.add_else ();
+                       ccode.add_else ();
 
-               var direct_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_complete"));
-               direct_call.add_argument (async_result_expr);
-               ccode.add_expression (direct_call);
+                       var direct_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_complete"));
+                       direct_call.add_argument (async_result_expr);
+                       ccode.add_expression (direct_call);
 
-               ccode.close ();
+                       ccode.close ();
+               }
 
                var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
                unref.add_argument (async_result_expr);
diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala
index 928e67b..99e17ff 100644
--- a/codegen/valagasyncmodule.vala
+++ b/codegen/valagasyncmodule.vala
@@ -30,7 +30,12 @@ public class Vala.GAsyncModule : GtkModule {
                data.add_field ("int", "_state_");
                data.add_field ("GObject*", "_source_object_");
                data.add_field ("GAsyncResult*", "_res_");
-               data.add_field ("GSimpleAsyncResult*", "_async_result");
+
+               if (context.require_glib_version (2, 36)) {
+                       data.add_field ("GTask*", "_async_result");
+               } else {
+                       data.add_field ("GSimpleAsyncResult*", "_async_result");
+               }
 
                if (m is CreationMethod) {
                        data.add_field ("GType", "object_type");
@@ -201,7 +206,13 @@ public class Vala.GAsyncModule : GtkModule {
                ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
                ccode.add_assignment (data_var, dataalloc);
 
-               var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
+               CCodeFunctionCall? create_result = null;
+
+               if (context.require_glib_version (2, 36)) {
+                       create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_task_new"));
+               } else {
+                       create_result = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_new"));
+               }
 
                var t = m.parent_symbol as TypeSymbol;
                if (!(m is CreationMethod) && m.binding == MemberBinding.INSTANCE &&
@@ -214,17 +225,44 @@ public class Vala.GAsyncModule : GtkModule {
                        create_result.add_argument (new CCodeConstant ("NULL"));
                }
 
+               if (context.require_glib_version (2, 36)) {
+                       Parameter cancellable_param = null;
+
+                       foreach (Parameter param in m.get_parameters ()) {
+                               if (param.variable_type is ObjectType && 
param.variable_type.data_type.get_full_name () == "GLib.Cancellable") {
+                                       cancellable_param = param;
+                                       break;
+                               }
+                       }
+
+                       if (cancellable_param == null) {
+                               create_result.add_argument (new CCodeConstant ("NULL"));
+                       } else {
+                               create_result.add_argument (new CCodeIdentifier (get_variable_cname 
(cancellable_param.name)));
+                       }
+               }
+
                create_result.add_argument (new CCodeIdentifier ("_callback_"));
                create_result.add_argument (new CCodeIdentifier ("_user_data_"));
-               create_result.add_argument (new CCodeIdentifier (get_ccode_real_name (m)));
+
+               if (!context.require_glib_version (2, 36)) {
+                       create_result.add_argument (new CCodeIdentifier (get_ccode_real_name (m)));
+               }
 
                ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, "_async_result"), 
create_result);
 
-               var set_op_res_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_set_op_res_gpointer"));
-               set_op_res_call.add_argument (new CCodeMemberAccess.pointer (data_var, "_async_result"));
-               set_op_res_call.add_argument (data_var);
-               set_op_res_call.add_argument (new CCodeIdentifier (get_ccode_real_name (m) + "_data_free"));
-               ccode.add_expression (set_op_res_call);
+               CCodeFunctionCall attach_data_call;
+
+               if (!context.require_glib_version (2, 36)) {
+                       attach_data_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_set_op_res_gpointer"));
+               } else {
+                       attach_data_call = new CCodeFunctionCall (new CCodeIdentifier 
("g_task_set_task_data"));
+               }
+
+               attach_data_call.add_argument (new CCodeMemberAccess.pointer (data_var, "_async_result"));
+               attach_data_call.add_argument (data_var);
+               attach_data_call.add_argument (new CCodeIdentifier (get_ccode_real_name (m) + "_data_free"));
+               ccode.add_expression (attach_data_call);
 
                if (m is CreationMethod) {
                        ccode.add_assignment (new CCodeMemberAccess.pointer (data_var, "object_type"), new 
CCodeIdentifier ("object_type"));
@@ -517,23 +555,47 @@ public class Vala.GAsyncModule : GtkModule {
 
                ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_"));
 
-               var simple_async_result_cast = new CCodeFunctionCall (new CCodeIdentifier 
("G_SIMPLE_ASYNC_RESULT"));
-               simple_async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
+               if (context.require_glib_version (2, 36)) {
+                       var async_result_cast = new CCodeFunctionCall (new CCodeIdentifier ("G_TASK"));
+                       async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
 
-               if (m.get_error_types ().size > 0) {
-                       // propagate error from async method
-                       var propagate_error = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_propagate_error"));
-                       propagate_error.add_argument (simple_async_result_cast);
-                       propagate_error.add_argument (new CCodeIdentifier ("error"));
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_task_propagate_pointer"));
+                       ccall.add_argument (async_result_cast);
 
-                       ccode.open_if (propagate_error);
-                       return_default_value (return_type);
-                       ccode.close ();
-               }
+                       if (m.get_error_types ().size > 0) {
+                               ccall.add_argument (new CCodeIdentifier ("error"));
+                       } else {
+                               ccall.add_argument (new CCodeConstant ("NULL"));
+                       }
 
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_get_op_res_gpointer"));
-               ccall.add_argument (simple_async_result_cast);
-               ccode.add_assignment (data_var, ccall);
+                       ccode.add_assignment (data_var, ccall);
+
+                       if (m.get_error_types ().size > 0) {
+                               var is_null = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new 
CCodeConstant ("NULL"), data_var);
+
+                               ccode.open_if (is_null);
+                               return_default_value (return_type);
+                               ccode.close ();
+                       }
+               } else {
+                       var simple_async_result_cast = new CCodeFunctionCall (new CCodeIdentifier 
("G_SIMPLE_ASYNC_RESULT"));
+                       simple_async_result_cast.add_argument (new CCodeIdentifier ("_res_"));
+
+                       if (m.get_error_types ().size > 0) {
+                               // propagate error from async method
+                               var propagate_error = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_propagate_error"));
+                               propagate_error.add_argument (simple_async_result_cast);
+                               propagate_error.add_argument (new CCodeIdentifier ("error"));
+
+                               ccode.open_if (propagate_error);
+                               return_default_value (return_type);
+                               ccode.close ();
+                       }
+
+                       var ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_get_op_res_gpointer"));
+                       ccall.add_argument (simple_async_result_cast);
+                       ccode.add_assignment (data_var, ccall);
+               }
 
                emit_context.push_symbol (m);
                foreach (Parameter param in m.get_parameters ()) {
@@ -701,18 +763,30 @@ public class Vala.GAsyncModule : GtkModule {
                        return;
                }
 
-               var set_error = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_set_from_error"));
-               set_error.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), 
"_async_result"));
+               var async_result_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), 
"_async_result");
+               CCodeFunctionCall set_error = null;
+
+               if (context.require_glib_version (2, 36)) {
+                       set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_task_return_error"));
+               } else {
+                       set_error = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_take_error"));
+               }
+               set_error.add_argument (async_result_expr);
                set_error.add_argument (error_expr);
                ccode.add_expression (set_error);
 
-               var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
-               free_error.add_argument (error_expr);
-               ccode.add_expression (free_error);
-
                append_local_free (current_symbol, false);
 
-               complete_async ();
+               if (context.require_glib_version (2, 36)) {
+                       // We already returned the error above, we must not return anything else here.
+                       var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+                       unref.add_argument (async_result_expr);
+                       ccode.add_expression (unref);
+
+                       ccode.add_return (new CCodeConstant ("FALSE"));
+               } else {
+                       complete_async ();
+               }
        }
 
        public override void visit_return_statement (ReturnStatement stmt) {
@@ -765,17 +839,26 @@ public class Vala.GAsyncModule : GtkModule {
                var res_ref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref"));
                res_ref.add_argument (new CCodeIdentifier ("res"));
 
+               CCodeFunctionCall ccall = null;
+
                // store reference to async result of inner async function in out async result
-               var ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_set_op_res_gpointer"));
+               if (context.require_glib_version (2, 36)) {
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_task_return_pointer"));
+               } else {
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_set_op_res_gpointer"));
+               }
+
                ccall.add_argument (new CCodeIdentifier ("user_data"));
                ccall.add_argument (res_ref);
                ccall.add_argument (new CCodeIdentifier ("g_object_unref"));
                ccode.add_expression (ccall);
 
-               // call user-provided callback
-               ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
-               ccall.add_argument (new CCodeIdentifier ("user_data"));
-               ccode.add_expression (ccall);
+               if (!context.require_glib_version (2, 36)) {
+                       // call user-provided callback
+                       ccall = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_complete"));
+                       ccall.add_argument (new CCodeIdentifier ("user_data"));
+                       ccode.add_expression (ccall);
+               }
 
                // free async result
                ccall = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 079ac52..08568cc 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -696,13 +696,24 @@ public class Vala.GDBusClientModule : GDBusModule {
                                ccall.add_argument (new CCodeConstant ("NULL"));
                                ccall.add_argument (cancellable);
 
+                               CCodeFunctionCall res_wrapper = null;
+
                                // use wrapper as source_object wouldn't be correct otherwise
-                               ccall.add_argument (new CCodeIdentifier (generate_async_callback_wrapper ()));
-                               var res_wrapper = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_new"));
-                               res_wrapper.add_argument (new CCodeCastExpression (new CCodeIdentifier 
("self"), "GObject *"));
-                               res_wrapper.add_argument (new CCodeIdentifier ("_callback_"));
-                               res_wrapper.add_argument (new CCodeIdentifier ("_user_data_"));
-                               res_wrapper.add_argument (new CCodeConstant ("NULL"));
+                               if (context.require_glib_version (2, 36)) {
+                                       ccall.add_argument (new CCodeIdentifier 
(generate_async_callback_wrapper ()));
+                                       res_wrapper = new CCodeFunctionCall (new CCodeIdentifier 
("g_task_new"));
+                                       res_wrapper.add_argument (new CCodeCastExpression (new 
CCodeIdentifier ("self"), "GObject *"));
+                                       res_wrapper.add_argument (new CCodeConstant ("NULL"));
+                                       res_wrapper.add_argument (new CCodeIdentifier ("_callback_"));
+                                       res_wrapper.add_argument (new CCodeIdentifier ("_user_data_"));
+                               } else {
+                                       ccall.add_argument (new CCodeIdentifier 
(generate_async_callback_wrapper ()));
+                                       res_wrapper = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_new"));
+                                       res_wrapper.add_argument (new CCodeCastExpression (new 
CCodeIdentifier ("self"), "GObject *"));
+                                       res_wrapper.add_argument (new CCodeIdentifier ("_callback_"));
+                                       res_wrapper.add_argument (new CCodeIdentifier ("_user_data_"));
+                                       res_wrapper.add_argument (new CCodeConstant ("NULL"));
+                               }
                                ccall.add_argument (res_wrapper);
 
                                ccode.add_expression (ccall);
@@ -718,12 +729,22 @@ public class Vala.GDBusClientModule : GDBusModule {
                        ccall.add_argument (connection);
 
                        // unwrap async result
-                       var inner_res = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_get_op_res_gpointer"));
-                       inner_res.add_argument (new CCodeCastExpression (new CCodeIdentifier ("_res_"), 
"GSimpleAsyncResult *"));
-                       ccall.add_argument (inner_res);
+                       if (context.require_glib_version (2, 36)) {
+                               var inner_res = new CCodeFunctionCall (new CCodeIdentifier 
("g_task_propagate_pointer"));
+                               inner_res.add_argument (new CCodeCastExpression (new CCodeIdentifier 
("_res_"), "GTask *"));
+                               inner_res.add_argument (new CCodeConstant ("NULL"));
+                               ccall.add_argument (inner_res);
 
-                       ccall.add_argument (new CCodeConstant ("error"));
-                       ccode.add_assignment (new CCodeIdentifier ("_reply_message"), ccall);
+                               ccall.add_argument (new CCodeConstant ("error"));
+                               ccode.add_assignment (new CCodeIdentifier ("_reply_message"), ccall);
+                       } else {
+                               var inner_res = new CCodeFunctionCall (new CCodeIdentifier 
("g_simple_async_result_get_op_res_gpointer"));
+                               inner_res.add_argument (new CCodeCastExpression (new CCodeIdentifier 
("_res_"), "GSimpleAsyncResult *"));
+                               ccall.add_argument (inner_res);
+
+                               ccall.add_argument (new CCodeConstant ("error"));
+                               ccode.add_assignment (new CCodeIdentifier ("_reply_message"), ccall);
+                       }
                }
 
                if (call_type == CallType.SYNC || call_type == CallType.FINISH) {


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