Portable concurrency  0.11.0

Build status Build status

CC0 licensed

Code documented

std::future done right. Simple to use portable implementation of the future/promise API inspired by the C++ Extensions for Concurrency TS and some parts of A Unified Executors Proposal for C++.

  • Minimum requred C++ standard: C++14
  • The only public dependency: standard library.
  • The only build dependency: gtest

Key features

  • Execcutor aware
    pc::static_thread_pool pool{5};
    pc::future<int> answer = pc::async(pool.executor(), [] {return 42;});
  • Designed to work with user provided executors
    template<> struct is_executor<QThreadPool*>: std::true_type {};
    }
    void post(QThreadPool*, pc::unique_function<void()>);
    pc::future<int> answer = pc::async(QThreadPool::globalInstance(), [] {return 42;});
  • Continuations support
    pc::static_thread_pool pool{5};
    asio::io_context io;
    pc::future<rapidjson::Document> res = pc::async(io.get_executor(), receive_document)
    .next(pool.executor(), parse_document);
  • when_all/when_any composition of futures
    pc::async(pool.executor(), fetch_from_cache),
    pc::async(io.get_executor(), receive_from_network)
    ).next([](auto when_any_res) {
    switch(when_any_res.index) {
    case 0: return std::get<0>(when_any_res.futures);
    case 1: return std::get<1>(when_any_res.futures);
    }
    });
  • future<future<T>> transparently unwrapped to future<T>
  • future<shared_future<T>> transparently unwrapped to shred_future<T>
  • Automatic task cancelation:
    • Not yet started functions passed to pc::async/pc::packaged_task or attached to intermediate futures as continuations may not be executed at all if future or all shared_future's on the result of continuations chain are destroyed.
    • future::detach() and shared_future::detach() functions allows to destroy future without cancelation of any tasks. ```cpp auto future = pc::async(pool.executor(), important_calculation) .next(io.get_executor(), important_io) .detach() .next(pool.executor(), not_so_important_calculations); `` important_calculationandimportant_ioare guarantied to be executed even in case of premature future destruction. *promise::is_awaiten()allows to check if there is afutureorshared_futurewaiting for value to be set on this promiseobject. *promise::promise(canceler_arg_t, CancelAction)` constructor allows to specify action which is called in case of cancelation via future destruction.
    • Additional then overload to check if task is canceled from the continuations function ```cpp pc::future<std::string> res = pc::async(pool.executor(), [] {return 42;}) .then([](pc::promise<std::string> p, pc::future<int> f) { std::string res; while (has_work_to_do()) { do_next_step(res, f); if (!p.is_awaiten()) return; } p.set_value(res); }); ```

Build

mkdir -p build/debug
cd build/debug
conan remote add pdeps https://api.bintray.com/conan/pdeps/deps
conan install --build=missing ../..
cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ../..
ninja
ninja test
post
void post(Executor exec, Functor func)
portable_concurrency::cxx14_v1::async
future< std::result_of_t< F(A...)> > async(E &&exec, F &&func, A &&... a)
Executor aware analog of the std::async.
Definition: async.h:61
portable_concurrency::cxx14_v1::future
The class template future provides a mechanism to access the result of asynchronous operations.
Definition: future.h:25
portable_concurrency::cxx14_v1::when_any
future< when_any_result< std::tuple< Futures... > > > when_any(Futures &&...)
portable_concurrency
The library public namespace.
Definition: algo_adapters.h:6