After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 789249 - Reentrancy issue if async functions get callback called before yield.
Reentrancy issue if async functions get callback called before yield.
Status: RESOLVED OBSOLETE
Product: vala
Classification: Core
Component: Async
unspecified
Other Linux
: Normal normal
: ---
Assigned To: Vala maintainers
Vala maintainers
Depends on:
Blocks: 786132
 
 
Reported: 2017-10-20 14:30 UTC by Carlos Garnacho
Modified: 2018-05-22 15:56 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
testcase showing the error. (369 bytes, text/x-vala)
2017-10-20 14:30 UTC, Carlos Garnacho
  Details
codegen: Make every co-routine state its own CodeBlock and bump state early (6.51 KB, patch)
2017-10-21 09:11 UTC, Rico Tzschichholz
none Details | Review
codegen: Make every co-routine state its own CodeBlock and bump state early (6.31 KB, patch)
2017-10-29 11:56 UTC, Rico Tzschichholz
none Details | Review
codegen: Make every co-routine state its own CodeBlock and bump state early (8.00 KB, patch)
2017-11-29 09:01 UTC, Rico Tzschichholz
none Details | Review

Description Carlos Garnacho 2017-10-20 14:30:49 UTC
Created attachment 361955 [details]
testcase showing the error.

The way valac works, the same function (suffixed _co()) handles both the first steps of the async function and the after effect, it just increments _data_->_state_ to 1 right before returning for the next time it's called.

There is a problem though if the async method manages to be completed before the yield call (eg. because of it being quickly dispatched in another thread). The _data_->_state_ change happens after the callback function is called, so it enters again on the _co() function with _state_ == 0, which does the first part of the function again.

It would be expected that at the time of reentering the _co() function, _state_ is 1 so it does handle the second part inside the first one, doing _data_->_state_ = 1 early in the _state0: path seems a thread safe way to get this.

I'm attaching a simple test case that asserts on the async foo() method if the portions before the yield get called more than once.
Comment 1 Rico Tzschichholz 2017-10-21 09:11:28 UTC
Created attachment 362002 [details] [review]
codegen: Make every co-routine state its own CodeBlock and bump state early
Comment 2 Rico Tzschichholz 2017-10-21 09:12:55 UTC
Of course this patch breaks the async/generator test. :(
Comment 3 Carlos Garnacho 2017-10-27 09:51:27 UTC
AFAICS the error is "legit", the patch is breaking code flow of that test. The unconditional ccode.close() before state>1 labels results in the wrong code block being closed, because the _state_1 label is nested inside the if (i % 2) check. Manually correcting that fixes the testcase.

Not sure if there's a better place to close the blocks though... I guess could be fixed with more intelligent tracking of the current block to ensure we are closing it if it matches the previous _state_X label's.
Comment 4 Rico Tzschichholz 2017-10-29 11:56:32 UTC
Created attachment 362485 [details] [review]
codegen: Make every co-routine state its own CodeBlock and bump state early
Comment 5 Rico Tzschichholz 2017-10-29 12:08:59 UTC
Thanks for looking into it. Seems like this can be accomplished easier than I expected, see the updated patch.
Comment 6 Rico Tzschichholz 2017-10-29 12:45:20 UTC
Nevermind, don't bother to test it.
Comment 7 Rico Tzschichholz 2017-11-29 09:01:25 UTC
Created attachment 364605 [details] [review]
codegen: Make every co-routine state its own CodeBlock and bump state early
Comment 8 GNOME Infrastructure Team 2018-05-22 15:56:13 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/vala/issues/601.