| Home | Libraries | People | FAQ | More

#### 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.