Opened 9 years ago
Last modified 9 years ago
#8600 assigned Bugs
wait_for_any hangs, if called with multiple copies of shared_future referencing same task
Reported by: | Owned by: | viboes | |
---|---|---|---|
Milestone: | To Be Determined | Component: | thread |
Version: | Boost 1.53.0 | Severity: | Problem |
Keywords: | Cc: |
Description
The following small test program shows the problem:
#include <iostream> #include <boost/thread.hpp> int calculate_the_answer_to_life_the_universe_and_everything() { return 42; } int main(int argc, char* argv[]) { boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything); boost::shared_future<int> fi1 = boost::shared_future<int>(pt.get_future()); boost::shared_future<int> fi2 = fi1; boost::thread task(boost::move(pt)); // launch task on a thread boost::wait_for_any(fi1, fi2); std::cout << "Wait for any returned\n"; return (0); }
This program hangs infinitely in the call to boost::wait_for_any. From the docs I would expect this to work, because it's allowed to copy shared_futures. If this is not allowed, a possibility would be needed, to find out, if two shared_futures point to the same task or not. Currently wait_for_any is unusable, if there are chances, that multiple shared_futures point to the same result.
Change History (6)
comment:1 by , 9 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
follow-up: 3 comment:2 by , 9 years ago
That's fine with me, as long as there is a possibility to detect, if two shared_futures point to the same object. Currently there is no such function, so there is no possibility to remove the duplicates before calling wait_for_any.
comment:3 by , 9 years ago
Replying to Martin Apel <martin.apel@…>:
That's fine with me, as long as there is a possibility to detect, if two shared_futures point to the same object. Currently there is no such function, so there is no possibility to remove the duplicates before calling wait_for_any.
I understand your concern. I will see what can be done.
comment:4 by , 9 years ago
What would you expect from the following code
int main(int argc, char* argv[]) { boost::packaged_task<int> pt(calculate_the_answer_to_life_the_universe_and_everything); boost::future<int> fi1 = pt.get_future(); boost::thread task(boost::move(pt)); // launch task on a thread boost::wait_for_any(fi1, fi1); std::cout << "Wait for any returned\n"; return (0); }
comment:5 by , 9 years ago
Interesting. I see that it's strange to explicitly pass two identical objects in there, but I would still expect it to wait correctly and not to silently hang infinitely. When called with iterators, this becomes more natural, because it's nothing special if a list contains the same item twice.
I would be perfectly happy to avoid this situation, if there only was a possibility to detect his. I have now found a workaround for my application, where I pass additional data and filter out futures based on this additional data. The best approach for me would be, if there was an operator== for shared_future objects, so I can compare, if they point to the same object or not. This would not incur any overhead and still make my use case possible.
comment:6 by , 9 years ago
I have requested some advice to the std-proposal forum and when_all, when_any should work when the futures share the same associated shared state. I will need to rethink the algorithm.
Thanks for catching this, even if I would not this to work.
I think the fix would be to document that the shared state of the N-futures must be different as a pre-condition.
I don't think the library must provide any check to avoid this usage.