Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

when_all, simple completion

For the case in which we must wait for all task functions to complete — but we don't need results (or expect exceptions) from any of them — we can write wait_all_simple() that looks remarkably like wait_first_simple(). The difference is that instead of our Done class, we instantiate a barrier and call its barrier::wait().

We initialize the barrier with (count+1) because we are launching count fibers, plus the wait() call within wait_all_simple() itself.

template< typename ... Fns >
void wait_all_simple( Fns && ... functions) {
    std::size_t count( sizeof ... ( functions) );
    // Initialize a barrier(count+1) because we'll immediately wait on it. We
    // don't want to wake up until 'count' more fibers wait on it. Even though
    // we'll stick around until the last of them completes, use shared_ptr
    // anyway because it's easier to be confident about lifespan issues.
    auto barrier( std::make_shared< boost::fibers::barrier >( count + 1) );
    wait_all_simple_impl( barrier, std::forward< Fns >( functions) ... );
    barrier->wait();
}

As stated above, the only difference between wait_all_simple_impl() and wait_first_simple_impl() is that the former calls barrier::wait() rather than Done::notify():

template< typename Fn, typename ... Fns >
void wait_all_simple_impl( std::shared_ptr< boost::fibers::barrier > barrier,
                           Fn && function, Fns && ... functions) {
    boost::fibers::fiber(
            std::bind(
                []( std::shared_ptr< boost::fibers::barrier > & barrier,
                    typename std::decay< Fn >::type & function) mutable {
                        function();
                        barrier->wait();
                },
                barrier,
                std::forward< Fn >( function)
            )).detach();
    wait_all_simple_impl( barrier, std::forward< Fns >( functions) ... );
}

You might call it like this:

wait_all_simple(
        [](){ sleeper("was_long",   150); },
        [](){ sleeper("was_medium", 100); },
        [](){ sleeper("was_short",   50); });

Control will not return from the wait_all_simple() call until the last of its task functions has completed.


PrevUpHomeNext