File unix.h¶
File List > coroutine > unix.h
Go to the documentation of this file.
#ifndef COROUTINE_SYSTEM_WRAPPER_H
#define COROUTINE_SYSTEM_WRAPPER_H
#if !(defined(unix) || defined(__APPLE__) || defined(__FreeBSD__))
#error "expect UNIX platform for this file"
#endif
#include <sys/event.h> // for BSD kqueue
#include <gsl/gsl>
#include <coroutine/return.h>
namespace coro {
class kqueue_owner final {
int64_t kqfd;
public:
kqueue_owner() noexcept(false);
~kqueue_owner() noexcept;
kqueue_owner(const kqueue_owner&) = delete;
kqueue_owner(kqueue_owner&&) = delete;
kqueue_owner& operator=(const kqueue_owner&) = delete;
kqueue_owner& operator=(kqueue_owner&&) = delete;
public:
void change(kevent64_s& req) noexcept(false);
ptrdiff_t events(const timespec& wait_time,
gsl::span<kevent64_s> list) noexcept(false);
public:
[[nodiscard]] auto submit(kevent64_s& req) noexcept {
class awaiter final : public suspend_always {
kqueue_owner& kq;
kevent64_s& req;
public:
constexpr awaiter(kqueue_owner& _kq, kevent64_s& _req)
: kq{_kq}, req{_req} {
}
public:
void await_suspend(coroutine_handle<void> coro) noexcept(false) {
if (req.udata == 0)
req.udata = reinterpret_cast<uint64_t>(coro.address());
return kq.change(req);
}
};
return awaiter{*this, req};
}
};
} // namespace coro
#endif // COROUTINE_SYSTEM_WRAPPER_H