17#ifndef TOOLBOX_IO_REACTOR_HPP
18#define TOOLBOX_IO_REACTOR_HPP
45 EndOfEventDispatch = 2,
55 constexpr Handle(std::nullptr_t =
nullptr) noexcept {}
64 : reactor_{rhs.reactor_}
68 rhs.reactor_ =
nullptr;
78 bool empty() const noexcept {
return reactor_ ==
nullptr; }
79 explicit operator bool() const noexcept {
return reactor_ !=
nullptr; }
80 auto fd() const noexcept {
return fd_; }
81 auto sid() const noexcept {
return sid_; }
83 void reset(std::nullptr_t =
nullptr) noexcept
86 reactor_->unsubscribe(fd_, sid_);
94 std::swap(reactor_, rhs.reactor_);
95 std::swap(fd_, rhs.fd_);
96 std::swap(sid_, rhs.sid_);
103 reactor_->set_events(fd_, sid_, events, slot, ec);
108 reactor_->set_events(fd_, sid_, events, slot);
110 void set_events(
unsigned events, std::error_code& ec)
noexcept
113 reactor_->set_events(fd_, sid_, events, ec);
118 reactor_->set_events(fd_, sid_, events);
124 reactor_->set_io_priority(fd_, sid_, priority);
129 int fd_{-1}, sid_{0};
132 explicit Reactor(std::size_t size_hint = 0);
144 [[nodiscard]]
Handle subscribe(
int fd,
unsigned events,
IoSlot slot);
149 return tqs_[
static_cast<size_t>(priority)].insert(expiry, interval, slot);
154 return tqs_[
static_cast<size_t>(priority)].insert(expiry, slot);
161 case HookType::EndOfCycleNoWait:
162 end_of_cycle_no_wait_hooks.push_back(hook);
164 case HookType::EndOfEventDispatch:
165 end_of_event_dispatch_hooks_.push_back(hook);
180 void do_wakeup() noexcept final;
187 void set_events(
int fd,
int sid,
unsigned events,
IoSlot slot,
std::error_code& ec) noexcept;
188 void set_events(
int fd,
int sid,
unsigned events,
IoSlot slot);
189 void set_events(
int fd,
int sid,
unsigned events,
std::error_code& ec) noexcept;
190 void set_events(
int fd,
int sid,
unsigned events);
191 void unsubscribe(
int fd,
int sid) noexcept;
192 void set_io_priority(
int fd,
int sid,
Priority priority) noexcept;
198 Priority priority = Priority::Low;
201 Epoll high_prio_epoll_;
202 std::vector<Data> data_;
203 EventFd notify_{0, EFD_NONBLOCK};
204 static_assert(
static_cast<int>(Priority::High) == 0);
205 static_assert(
static_cast<int>(Priority::Low) == 1);
207 std::array<TimerQueue, 2> tqs_{tp_, tp_};
208 HookList end_of_cycle_no_wait_hooks, end_of_event_dispatch_hooks_;
209 Micros priority_io_poll_threshold = Micros::max();
210 WallTime last_time_priority_io_polled_{};
212 bool currently_handling_priority_events_{
false};