]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Bug 571263 – make yielding functions dispatch results to mainloop
authorRyan Lortie <desrt@desrt.ca>
Wed, 11 Feb 2009 16:03:53 +0000 (16:03 +0000)
committerRyan Lortie <ryanl@src.gnome.org>
Wed, 11 Feb 2009 16:03:53 +0000 (16:03 +0000)
2009-02-11  Ryan Lortie  <desrt@desrt.ca>

        Bug 571263 – make yielding functions dispatch results to mainloop

        * gobject/valaccodemethodmodule.vala:
        * valagasyncmodule.vala:

        Create simple async result from _async entry function and use it when
        doing return; throw; or at the end of the function.  Fix return
        statements for the async case.  Dispatch via idle handler in the case
        that we are returning without having yielded.

svn path=/trunk/; revision=2430

ChangeLog
gobject/valaccodemethodmodule.vala
gobject/valagasyncmodule.vala

index 9be6b85ef690c946eaf07dad601dda1e47cb7ba6..94b3d3967059a30d7a087829e246cbec6ea13db8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2009-02-11  Ryan Lortie  <desrt@desrt.ca>
+
+       Bug 571263 – make yielding functions dispatch results to mainloop
+
+       * gobject/valaccodemethodmodule.vala:
+       * valagasyncmodule.vala:
+       
+       Create simple async result from _async entry function and use it when
+       doing return; throw; or at the end of the function.  Fix return
+       statements for the async case.  Dispatch via idle handler in the case
+       that we are returning without having yielded.
+
 2009-02-11  Ryan Lortie  <desrt@desrt.ca>
 
        Bug 566363 – yielding functions that throw don't work
index ee5abed114df7b1d1038014956c0d1e210e7512a..ad71357d3475a402b1259284b0686f75ff7d06b5 100644 (file)
@@ -111,6 +111,35 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                }
        }
 
+       public CCodeStatement complete_async () {
+               var complete_block = new CCodeBlock ();
+
+               var direct_block = new CCodeBlock ();
+               var direct_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
+               var async_result_expr = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result");
+               direct_call.add_argument (async_result_expr);
+               direct_block.add_statement (new CCodeExpressionStatement (direct_call));
+
+               var idle_block = new CCodeBlock ();
+               var idle_call = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete_in_idle"));
+               idle_call.add_argument (async_result_expr);
+               idle_block.add_statement (new CCodeExpressionStatement (idle_call));
+
+               var state = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "state");
+               var zero = new CCodeConstant ("0");
+               var state_is_zero = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, state, zero);
+               var dispatch = new CCodeIfStatement (state_is_zero, idle_block, direct_block);
+               complete_block.add_statement (dispatch);
+
+               var unref = new CCodeFunctionCall (new CCodeIdentifier ("g_object_unref"));
+               unref.add_argument (async_result_expr);
+               complete_block.add_statement (new CCodeExpressionStatement (unref));
+
+               complete_block.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+
+               return complete_block;
+       }
+
        public override void visit_method (Method m) {
                var old_type_symbol = current_type_symbol;
                var old_symbol = current_symbol;
@@ -281,23 +310,8 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                                        // coroutine body
                                        cswitch.add_statement (function.block);
 
-                                       // complete async call by invoking callback
-                                       var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
-                                       object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
-                                       object_creation.add_argument (new CCodeConstant ("0"));
-                                       object_creation.add_argument (new CCodeConstant ("NULL"));
-
-                                       var async_result_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
-                                       async_result_creation.add_argument (object_creation);
-                                       async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
-                                       async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
-                                       async_result_creation.add_argument (new CCodeIdentifier ("data"));
-
-                                       var completecall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
-                                       completecall.add_argument (async_result_creation);
-                                       cswitch.add_statement (new CCodeExpressionStatement (completecall));
-
-                                       cswitch.add_statement (new CCodeReturnStatement (new CCodeConstant ("FALSE")));
+                                       // epilogue
+                                       cswitch.add_statement (complete_async ());
 
                                        co_function.block = new CCodeBlock ();
                                        co_function.block.add_statement (cswitch);
@@ -924,3 +938,5 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
                }
        }
 }
+
+// vim:sw=8 noet
index b75699ac398de8f1cce81bd060ce4e8153ba5c24..01177e50193fceedd0d3b3838e473b01db494ae3 100644 (file)
@@ -44,9 +44,8 @@ internal class Vala.GAsyncModule : GSignalModule {
                closure_struct = new CCodeStruct ("_" + dataname);
 
                closure_struct.add_field ("int", "state");
-               closure_struct.add_field ("GAsyncReadyCallback", "callback");
-               closure_struct.add_field ("gpointer", "user_data");
                closure_struct.add_field ("GAsyncResult*", "res");
+               closure_struct.add_field ("GSimpleAsyncResult*", "_async_result");
 
                if (m.binding == MemberBinding.INSTANCE) {
                        var type_sym = (TypeSymbol) m.parent_symbol;
@@ -82,8 +81,25 @@ internal class Vala.GAsyncModule : GSignalModule {
                asyncblock.add_statement (datadecl);
                asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), dataalloc)));
 
-               asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"), new CCodeIdentifier ("callback"))));
-               asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"), new CCodeIdentifier ("user_data"))));
+               var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
+
+               var cl = m.parent_symbol as Class;
+               if (m.binding == MemberBinding.INSTANCE &&
+                   cl != null && cl.is_subtype_of (gobject_type)) {
+                       create_result.add_argument (new CCodeIdentifier ("self"));
+               } else {
+                       var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
+                       object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
+                       object_creation.add_argument (new CCodeConstant ("0"));
+                       object_creation.add_argument (new CCodeConstant ("NULL"));
+                       create_result.add_argument (object_creation);
+               }
+
+               create_result.add_argument (new CCodeIdentifier ("callback"));
+               create_result.add_argument (new CCodeIdentifier ("user_data"));
+               create_result.add_argument (new CCodeIdentifier (m.get_real_cname () + "_async"));
+
+               asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "_async_result"), create_result)));
 
                if (m.binding == MemberBinding.INSTANCE) {
                        asyncblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "self"), new CCodeIdentifier ("self"))));
@@ -283,25 +299,11 @@ internal class Vala.GAsyncModule : GSignalModule {
                }
 
                var block = new CCodeBlock ();
-               var cl = current_method.parent_symbol as Class;
-
-               var report_idle = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_report_gerror_in_idle"));
-
-               if (current_method.binding == MemberBinding.INSTANCE &&
-                   cl != null && cl.is_subtype_of (gobject_type)) {
-                       report_idle.add_argument (new CCodeIdentifier ("self"));
-               } else {
-                       var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
-                       object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
-                       object_creation.add_argument (new CCodeConstant ("0"));
-                       object_creation.add_argument (new CCodeConstant ("NULL"));
-                       report_idle.add_argument (object_creation);
-               }
 
-               report_idle.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
-               report_idle.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
-               report_idle.add_argument (error_expr);
-               block.add_statement (new CCodeExpressionStatement (report_idle));
+               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"));
+               set_error.add_argument (error_expr);
+               block.add_statement (new CCodeExpressionStatement (set_error));
 
                var free_error = new CCodeFunctionCall (new CCodeIdentifier ("g_error_free"));
                free_error.add_argument (error_expr);
@@ -311,10 +313,35 @@ internal class Vala.GAsyncModule : GSignalModule {
                append_local_free (current_symbol, free_locals, false);
                block.add_statement (free_locals);
 
-               block.add_statement (new CCodeReturnStatement ());
+               block.add_statement (complete_async ());
 
                return block;
        }
+
+       public override void visit_return_statement (ReturnStatement stmt) {
+               if (current_method == null || !current_method.coroutine) {
+                       base.visit_return_statement (stmt);
+                       return;
+               }
+
+               stmt.accept_children (codegen);
+
+               var result_block = new CCodeBlock ();
+               stmt.ccodenode = result_block;
+
+               if (stmt.return_expression != null) {
+                       var result_var = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "result");
+                       var assign_result = new CCodeAssignment (result_var, (CCodeExpression) stmt.return_expression.ccodenode);
+                       result_block.add_statement (new CCodeExpressionStatement (assign_result));
+                       create_temp_decl (stmt, stmt.return_expression.temp_vars);
+               }
+
+               var free_locals = new CCodeFragment ();
+               append_local_free (current_symbol, free_locals, false);
+               result_block.add_statement (free_locals);
+
+               result_block.add_statement (complete_async ());
+       }
 }
 
 // vim:sw=8 noet