Hi all. I have implemented a patch for vala for safe manage situation
like the one describe on this discution. The solution to call
Idle.add(myfunc.callback) is not good for 2 reason:
1. performance. you go back to the mainloop
2. Idle.add has to have less priority that the function that you have to wakeup.

my patch is attached. Can you test this patch with your code without
modification for  Idle.add(myfunc.callback) . If it is working I will
try to put in on vala bugzilla, and, if we are lucky, it will be
integrated officially.

regards and thanks for any feedback


2016-03-20 14:02 GMT+01:00 mar...@saepia.net <mar...@saepia.net>:
> Felipe, SIGSTOP is real signal issued by the OS that has stopped the
> execution.
>
> Michele, it seems you were right. I've changed all callback() calls to
> Idle.add(myfunc.callback) so I am 100% sure that they are async and crashes
> stopped to occur.
>
> I must admit that it was one of the weirdest bugs I've encountered ever. It
> caused for instance Soup.Session from libsoup to stop using custom
> TlsDatabase after some time and returing SSL error for all connections, or
> crashes in GLib's memory allocators.
>
> Awkward. I think such warning that code must be async in 100% cases should
> be explicitely added to the documentation.
>
> m.
>
> 2016-03-18 16:29 GMT+01:00 Felipe Lavratti <felipe...@gmail.com>:
>>
>> Hey, Why did you get a SIGSTOP on top of the stack trace? Is it emitted
>> from the code you use to print the stacktrace or it is the real signal that
>> stopped execution?
>>
>> On Fri, Mar 18, 2016 at 6:22 AM mar...@saepia.net <mar...@saepia.net>
>> wrote:
>>>
>>> Felipe, it's non threaded.
>>>
>>> Michele, good hint! I will check that.
>>>
>>> m.
>>>
>>> 2016-03-18 6:47 GMT+01:00 <michele.dioni...@gmail.com>:
>>>>
>>>> A crash can happes if you call the callback to wakeup before the yield.
>>>> Are you completly sure that your code is completly asyncrounous in any
>>>> condition.
>>>>
>>>> Il ven mar 18 01:05:05 2016 GMT+0100, Felipe Lavratti scrive:
>>>> > Hey Marcin,
>>>> >
>>>> > Just wondering,
>>>> > Is your program using threading or any threaded object that is handled
>>>> > in
>>>> > this part of code?
>>>> >
>>>> >
>>>> >
>>>> >
>>>> > On Thu, Mar 17, 2016 at 20:44 mar...@saepia.net <mar...@saepia.net>
>>>> > wrote:
>>>> >
>>>> > > Hi all,
>>>> > >
>>>> > > I encounter random crashes in my app, which (it's my guess) is
>>>> > > triggered
>>>> > > when I call callback in async method.
>>>> > >
>>>> > > Such as
>>>> > >
>>>> > > public async void something() {
>>>> > >   SourceFunc callback_ref = something.callback;
>>>> > >
>>>> > >   do_something_that_calls_another_callback(() => {
>>>> > >     callback_ref(); // here's crash happening. approximately 1/10000
>>>> > > calls
>>>> > >   });
>>>> > >
>>>> > >   yield;
>>>> > > }
>>>> > >
>>>> > > The chain of async calls is nested.
>>>> > >
>>>> > > I get stack traces like this:
>>>> > >
>>>> > >
>>>> > > https://gist.githubusercontent.com/mspanc/9ca4795f48e56149a9a2/raw/9be534c66409b26820a66d54f8610f2aa6306e1e/gistfile1.txt
>>>> > >
>>>> > > It's rather hard to believe that such basic thing as memory
>>>> > > allocation is
>>>> > > broken in GLib.
>>>> > >
>>>> > > Crash happens totally randomly, once per 1-3 days. You can imagine
>>>> > > how hard
>>>> > > is to collect test cases. I am trying to hunt more stack traces in
>>>> > > order to
>>>> > > find a pattern, but maybe in the meantime anyone here can share
>>>> > > experience
>>>> > > in debugging such issues?
>>>> > >
>>>> > > Or maybe there are some well-known bugs or antipatterns related to
>>>> > > async
>>>> > > functions that should be avoided?
>>>> > >
>>>> > > I use GLib 2.44 & Vala 0.30.0. I will try to upgrade to 2.46 but I
>>>> > > see
>>>> > > nothing related in the changelog.
>>>> > >
>>>> > > m.
>>>> > > _______________________________________________
>>>> > > vala-list mailing list
>>>> > > vala-list@gnome.org
>>>> > > https://mail.gnome.org/mailman/listinfo/vala-list
>>>> > >
>>>> > _______________________________________________
>>>> > vala-list mailing list
>>>> > vala-list@gnome.org
>>>> > https://mail.gnome.org/mailman/listinfo/vala-list
>>>> >
>>>
>>>
>
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;
_______________________________________________
vala-list mailing list
vala-list@gnome.org
https://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to