2020-08-24 03:13:12 +00:00
|
|
|
#include<Ev/Io.hpp>
|
|
|
|
|
#include<Ev/yield.hpp>
|
|
|
|
|
#include<Util/make_unique.hpp>
|
|
|
|
|
#include<ev.h>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
void yield_handler(EV_P_ ev_idle* raw_idler, int) {
|
|
|
|
|
/* Acquire responsibility. */
|
|
|
|
|
auto idler = std::unique_ptr<ev_idle>(raw_idler);
|
|
|
|
|
ev_idle_stop(EV_A_ idler.get());
|
|
|
|
|
auto ppass = std::unique_ptr<std::function<void()>>(
|
|
|
|
|
(std::function<void()>*) idler->data
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* Move off the pass function. */
|
|
|
|
|
auto pass = std::move(*ppass);
|
|
|
|
|
|
|
|
|
|
/* Release resources. */
|
|
|
|
|
idler = nullptr;
|
|
|
|
|
ppass = nullptr;
|
|
|
|
|
|
|
|
|
|
pass();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
namespace Ev {
|
|
|
|
|
|
|
|
|
|
Io<void> yield() {
|
|
|
|
|
return Io<void>([]( std::function<void()> pass
|
|
|
|
|
, std::function<void(std::exception_ptr)> fail
|
|
|
|
|
) {
|
|
|
|
|
auto ppass = Util::make_unique<std::function<void()>>(
|
|
|
|
|
std::move(pass)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
auto idler = Util::make_unique<ev_idle>();
|
|
|
|
|
ev_idle_init(idler.get(), &yield_handler);
|
|
|
|
|
/* Release responsibility to C code. */
|
|
|
|
|
idler->data = ppass.release();
|
|
|
|
|
ev_idle_start(EV_DEFAULT_ idler.release());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 12:29:45 +08:00
|
|
|
Io<void> yield(std::size_t num_yields) {
|
|
|
|
|
if (num_yields == 0)
|
|
|
|
|
return Ev::lift();
|
|
|
|
|
return yield().then([num_yields]() {
|
|
|
|
|
return yield(num_yields - 1);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-24 03:13:12 +00:00
|
|
|
}
|