diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala index d147eb1..cbd6e1a 100644 --- a/codegen/valaccodemethodmodule.vala +++ b/codegen/valaccodemethodmodule.vala @@ -456,6 +456,14 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { if (!m.is_abstract || (m.is_abstract && current_type_symbol is Class)) { if (m.body != null) { if (m.coroutine) { + 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.open_switch (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_")); // initial coroutine state @@ -475,7 +483,8 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule { ccode.close (); // coroutine body - ccode.add_label ("_state_0"); + 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..6a24300 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"); @@ -200,6 +201,7 @@ public class Vala.GAsyncModule : GtkModule { ccode.add_declaration (dataname + "*", new CCodeVariableDeclarator ("_data_")); ccode.add_assignment (data_var, dataalloc); + ccode.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_in_progress_"), new CCodeConstant ("-1")); var create_result = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new")); @@ -663,10 +665,18 @@ 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.add_assignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), "_state_in_progress_"), new CCodeConstant (state.to_string ())); ccode.add_statement (new CCodeEmptyStatement ()); return;