You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Many code paths (dynamically/iteratively) generate tasks that need to be waited on.
Currently one needs to make a temporary storage for all of them and then create when_all composition.
The proposal api simply separates the when_all initialization and addition steps, allowing it to be easily used with loops, generators, fold expressions etc..
Please let me know if the feature is ok with you and any comments on proposed code below:
I can make a pr then..
// On a side note, while it should be possible to make an analogue for when_any, i dont imagine (many) use-cases for that rn. Therefore not suggesting to add it.
/// Returns when_all state that can be used with tasks from generators without intermediate storage/// Use operator(task) to fill it with tasks and/// readyTask is the composite result tasktemplate<typename Ttask = async::task<void> >
autowhen_all_iterative(size_t total_count)
{
typedeftypename std::decay<Ttask>::type task_type;
typedef std::vector<task_type> result_type;
structwhen_all_iterative_state
{
typedef async::detail::when_all_state<result_type> state_type;
voidoperator() (task_type&& source_task)
{
LIBASYNC_ASSERT(state, std::logic_error, "Adding to empty when_all");
// Add a continuation to each task to add its result to the shared state// Last task sets the event result
LIBASYNC_TRY {
source_task.then(async::inline_scheduler(), async::detail::when_all_func_range<task_type, result_type>(next_index++, async::detail::ref_count_ptr<async::detail::when_all_state<result_type>>(state)));
} LIBASYNC_CATCH(...) {
// Make sure we don't leak memory if then() throwsaddFailed(1);
LIBASYNC_RETHROW();
}
}
voidsetTotal(size_t total_count)
{
LIBASYNC_ASSERT(!state, std::logic_error, "Initializing state twice");
state = newstate_type(total_count);
state->result.resize(total_count);
readyTask = state->event.get_task();
}
voidaddFailed(size_t failed = 1)
{
LIBASYNC_ASSERT(state, std::logic_error, "Adding to empty when_all");
state->remove_ref(failed);
next_index += failed;
}
protected:
state_type* state = nullptr;
size_t next_index = 0;
public:
async::task<result_type> readyTask = async::make_task<result_type>({});
} state;
if (total_count)
state.setTotal(total_count);
return state;
}
The text was updated successfully, but these errors were encountered:
Many code paths (dynamically/iteratively) generate tasks that need to be waited on.
Currently one needs to make a temporary storage for all of them and then create when_all composition.
The proposal api simply separates the when_all initialization and addition steps, allowing it to be easily used with loops, generators, fold expressions etc..
Please let me know if the feature is ok with you and any comments on proposed code below:
I can make a pr then..
// On a side note, while it should be possible to make an analogue for when_any, i dont imagine (many) use-cases for that rn. Therefore not suggesting to add it.
The text was updated successfully, but these errors were encountered: