-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Speculative fix for vroom issue #512
Conversation
src/vroom_write.cc
Outdated
@@ -381,7 +381,7 @@ void vroom_write_out( | |||
auto end = begin + num_lines; | |||
futures[idx][t++] = std::async( | |||
fill_buf, | |||
input, | |||
std::ref(input), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Davis! This has a great ratio of "size of fix" to "size of headache / anxiety about problem" 😅
My guess as to what happens is:
Now, these Line 406 in 3691c68
Which means that, at least in theory, I think Very good explanation of async argument destruction time: I am still not 100% sure why fiddling with the preserve list on the cpp11 side (that commit where stuff started breaking) triggered this to show up, but I am now fairly confident that vroom is where the fix should come from. |
It feels like I should merge this @DavisVaughan and move towards release. How do you feel about that? |
Yes I agree |
We started seeing random-looking test failures on CRAN on August 17. We have now found out that on our Windows machine, write_lines with multiple threads and cause R to hang forever. This happens only with some input data, and even with the same data only in one of about 300 cases. This would also be fixed with the very recent change to readr/vroom: tidyverse/vroom#512 But that fix is not on CRAN yet.
Fixes #510
I don't think we should merge this yet, but I do think it should fix the issue.
Has something to do with the fact that
std::async
will force a copy of the arguments you pass it, even if they ultimately get called inf
asconst reference
, becausestd::async
has no way of knowing that.So to perfect forward a const reference, the right way to do it is to wrap the thing you want a reference to in
std::ref()
and pass that along instead.I am not entirely sure why this broke with new cpp11. Probably some cpp11 destructor is being run (on the thread?) that unprotects the underlying SEXP too early.
https://stackoverflow.com/questions/18359864/passing-arguments-to-stdasync-by-reference-fails
https://www.linkedin.com/pulse/careful-when-using-const-reference-stdthread-stdasync-bhavith-c-achar