separate make coroutines into their own header
parent
621bad7474
commit
edd60babdd
|
@ -29,13 +29,13 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <future>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
#include <ostd/range.hh>
|
#include <ostd/range.hh>
|
||||||
#include <ostd/string.hh>
|
#include <ostd/string.hh>
|
||||||
#include <ostd/coroutine.hh>
|
|
||||||
#include <ostd/thread_pool.hh>
|
#include <ostd/thread_pool.hh>
|
||||||
#include <ostd/path.hh>
|
#include <ostd/path.hh>
|
||||||
#include <ostd/io.hh>
|
#include <ostd/io.hh>
|
||||||
|
@ -221,54 +221,6 @@ struct make_task {
|
||||||
virtual void add_task(std::future<void> f) = 0;
|
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 {
|
struct make {
|
||||||
using task_factory = std::function<
|
using task_factory = std::function<
|
||||||
make_task *(string_range, std::vector<string_range>, make_rule &)
|
make_task *(string_range, std::vector<string_range>, make_rule &)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
/** @} */
|
Loading…
Reference in New Issue