separate make coroutines into their own header

master
Daniel Kolesa 2018-04-23 21:57:50 +02:00
parent 621bad7474
commit edd60babdd
2 changed files with 88 additions and 49 deletions

View File

@ -29,13 +29,13 @@
#include <thread>
#include <mutex>
#include <condition_variable>
#include <future>
#include <stdexcept>
#include <chrono>
#include <type_traits>
#include <ostd/range.hh>
#include <ostd/string.hh>
#include <ostd/coroutine.hh>
#include <ostd/thread_pool.hh>
#include <ostd/path.hh>
#include <ostd/io.hh>
@ -221,54 +221,6 @@ struct make_task {
virtual void add_task(std::future<void> f) = 0;
};
namespace detail {
struct make_task_coro: make_task {
make_task_coro() = delete;
make_task_coro(
string_range target, std::vector<string_range> deps, make_rule &rl
): p_coro(
[target, deps = std::move(deps), &rl](auto) mutable {
rl.call(target, iterator_range<string_range *>(
deps.data(), deps.data() + deps.size()
));
}
) {}
bool done() const {
return !p_coro;
}
void resume() {
p_coro.resume();
}
void add_task(std::future<void> f) {
for (;;) {
auto fs = f.wait_for(std::chrono::seconds(0));
if (fs != std::future_status::ready) {
/* keep yielding until ready */
auto &cc = static_cast<coroutine<void()> &>(
*coroutine_context::current()
);
(coroutine<void()>::yield_type(cc))();
} else {
break;
}
}
}
private:
coroutine<void()> p_coro;
};
}
inline make_task *make_task_coroutine(
string_range target, std::vector<string_range> deps, make_rule &rl
) {
return new detail::make_task_coro{target, std::move(deps), rl};
}
struct make {
using task_factory = std::function<
make_task *(string_range, std::vector<string_range>, make_rule &)

View File

@ -0,0 +1,87 @@
/** @addtogroup Build
* @{
*/
/** @file make_coroutine.hh
*
* @brief Coroutine integration for ostd::build::make.
*
* This file provides an implementation of coroutine-based make tasks,
* allowing for seamless synchronous-looking build rules.
*
* @copyright See COPYING.md in the project tree for further information.
*/
#ifndef OSTD_BUILD_MAKE_COROUTINE_HH
#define OSTD_BUILD_MAKE_COROUTINE_HH
#include <vector>
#include <future>
#include <ostd/string.hh>
#include <ostd/coroutine.hh>
#include <ostd/build/make.hh>
namespace ostd {
namespace build {
/** @addtogroup Build
* @{
*/
namespace detail {
struct make_task_coro: make_task {
make_task_coro() = delete;
make_task_coro(
string_range target, std::vector<string_range> deps, make_rule &rl
): p_coro(
[target, deps = std::move(deps), &rl](auto) mutable {
rl.call(target, iterator_range<string_range *>(
deps.data(), deps.data() + deps.size()
));
}
) {}
bool done() const {
return !p_coro;
}
void resume() {
p_coro.resume();
}
void add_task(std::future<void> f) {
for (;;) {
auto fs = f.wait_for(std::chrono::seconds(0));
if (fs != std::future_status::ready) {
/* keep yielding until ready */
auto &cc = static_cast<coroutine<void()> &>(
*coroutine_context::current()
);
(coroutine<void()>::yield_type(cc))();
} else {
break;
}
}
}
private:
coroutine<void()> p_coro;
};
}
inline make_task *make_task_coroutine(
string_range target, std::vector<string_range> deps, make_rule &rl
) {
return new detail::make_task_coro{target, std::move(deps), rl};
}
/** @} */
} /* namespace build */
} /* namespace ostd */
#endif
/** @} */