diff options
author | Ryan Lortie <desrt@desrt.ca> | 2009-02-11 16:03:53 +0000 |
---|---|---|
committer | Ryan Lortie <ryanl@src.gnome.org> | 2009-02-11 16:03:53 +0000 |
commit | 95883d2d9d67577282dfc53878656b50dfe38d7c (patch) | |
tree | aac17476904b062d2fdb64edb2b319cb1e966b0c | |
parent | 12f57c93e4d8a328490faca70fe2f40f17652082 (diff) | |
download | vala-95883d2d9d67577282dfc53878656b50dfe38d7c.tar.gz |
Bug 571263 – make yielding functions dispatch results to mainloop
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
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | gobject/valaccodemethodmodule.vala | 50 | ||||
-rw-r--r-- | gobject/valagasyncmodule.vala | 73 |
3 files changed, 95 insertions, 40 deletions
@@ -1,5 +1,17 @@ 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 * gobject/valagerrormodule.vala: diff --git a/gobject/valaccodemethodmodule.vala b/gobject/valaccodemethodmodule.vala index ee5abed11..ad71357d3 100644 --- a/gobject/valaccodemethodmodule.vala +++ b/gobject/valaccodemethodmodule.vala @@ -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 diff --git a/gobject/valagasyncmodule.vala b/gobject/valagasyncmodule.vala index b75699ac3..01177e501 100644 --- a/gobject/valagasyncmodule.vala +++ b/gobject/valagasyncmodule.vala @@ -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 |