diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index d147eb1..1347a26 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -476,6 +476,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { // coroutine body ccode.add_label ("_state_0"); + ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_in_progress_"), new CCodeConstant ("0")); } if (m.closure) { diff --git a/codegen/valagasyncmodule.vala b/codegen/valagasyncmodule.vala index 928e67b..d0c8001 100644 --- a/codegen/valagasyncmodule.vala +++ b/codegen/valagasyncmodule.vala @@ -28,6 +28,7 @@ public class Vala.GAsyncModule : GtkModule { var data = new CCodeStruct ("_" + dataname); data.add_field ("int", "_state_"); + data.add_field ("int", "_state_in_progress_"); data.add_field ("GObject*", "_source_object_"); data.add_field ("GAsyncResult*", "_res_"); data.add_field ("GSimpleAsyncResult*", "_async_result"); @@ -663,10 +664,25 @@ public class Vala.GAsyncModule : GtkModule { if (stmt.yield_expression == null) { int state = next_coroutine_state++; - + ccode.open_if( + new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, + new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_"), + new CCodeConstant (state.to_string ()) ) ); ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_"), new CCodeConstant (state.to_string ())); ccode.add_return (new CCodeConstant ("FALSE")); + ccode.add_else(); + ccode.add_statement (new CCodeComment ("callback to wakeup yield is already called, so no wait")); + ccode.close(); + ccode.add_label ("_state_%d".printf (state)); + ccode.open_if( + new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, + new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_in_progress_"), + new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_") ) ); + ccode.add_statement (new CCodeComment ("callback is called too early before that yield stantment is really reached")); + ccode.add_return (new CCodeConstant ("FALSE")); + ccode.close(); + ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_in_progress_"), new CCodeConstant (state.to_string ())); ccode.add_statement (new CCodeEmptyStatement ()); return;