// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2019 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_CTX_CONCURRENT_H namespace ircd::ctx { template struct concurrent; } template struct ircd::ctx::concurrent { using closure = std::function; pool &p; closure c; dock d; size_t snd {0}; size_t rcv {0}; size_t fin {0}; std::exception_ptr eptr; template void operator()(V&&); void wait(); concurrent(pool &, closure); ~concurrent() noexcept; }; template ircd::ctx::concurrent::concurrent(pool &p, closure c) :p{p} ,c{std::move(c)} {} template ircd::ctx::concurrent::~concurrent() noexcept { const uninterruptible::nothrow ui; this->wait(); } template void ircd::ctx::concurrent::wait() { d.wait([this]() noexcept { return snd == fin; }); } template template void ircd::ctx::concurrent::operator()(V&& v) { ++snd; p([this, v(std::move(v))]() noexcept { ++rcv; try { c(std::move(v)); } catch(...) { eptr = std::current_exception(); } ++fin; d.notify_all(); }); if(eptr) std::rethrow_exception(eptr); }