17#ifndef TOOLBOX_IO_REACTOR_HPP
18#define TOOLBOX_IO_REACTOR_HPP
46 EndOfEventDispatch = 2,
56 constexpr Handle(std::nullptr_t =
nullptr) noexcept {}
65 : reactor_{rhs.reactor_}
69 rhs.reactor_ =
nullptr;
79 bool empty() const noexcept {
return reactor_ ==
nullptr; }
80 explicit operator bool() const noexcept {
return reactor_ !=
nullptr; }
81 auto fd() const noexcept {
return fd_; }
82 auto sid() const noexcept {
return sid_; }
84 void reset(std::nullptr_t =
nullptr) noexcept
87 reactor_->unsubscribe(fd_, sid_);
95 std::swap(reactor_, rhs.reactor_);
96 std::swap(fd_, rhs.fd_);
97 std::swap(sid_, rhs.sid_);
104 reactor_->set_events(fd_, sid_, events, slot, ec);
109 reactor_->set_events(fd_, sid_, events, slot);
111 void set_events(
unsigned events, std::error_code& ec)
noexcept
114 reactor_->set_events(fd_, sid_, events, ec);
119 reactor_->set_events(fd_, sid_, events);
125 reactor_->set_io_priority(fd_, sid_, priority);
130 int fd_{-1}, sid_{0};
133 explicit Reactor(std::size_t size_hint = 0);
145 [[nodiscard]]
Handle subscribe(
int fd,
unsigned events,
IoSlot slot);
150 return tqs_[
static_cast<size_t>(priority)].insert(expiry, interval, slot);
155 return tqs_[
static_cast<size_t>(priority)].insert(expiry, slot);
162 case HookType::EndOfCycleNoWait:
163 end_of_cycle_no_wait_hooks.push_back(hook);
165 case HookType::EndOfEventDispatch:
166 end_of_event_dispatch_hooks_.push_back(hook);
176 void yield() noexcept;
178 void set_high_priority_poll_threshold(
Micros thresh) { priority_io_poll_threshold_ = thresh; }
185 void do_wakeup() noexcept final;
192 void set_events(
int fd,
int sid,
unsigned events,
IoSlot slot,
std::error_code& ec) noexcept;
193 void set_events(
int fd,
int sid,
unsigned events,
IoSlot slot);
194 void set_events(
int fd,
int sid,
unsigned events,
std::error_code& ec) noexcept;
195 void set_events(
int fd,
int sid,
unsigned events);
196 void unsubscribe(
int fd,
int sid) noexcept;
197 void set_io_priority(
int fd,
int sid,
Priority priority) noexcept;
198 int do_io_priority_poll(
WallTime now) noexcept;
199 int do_user_priority_poll(
WallTime now) noexcept;
205 Priority priority = Priority::Low;
209 std::vector<Data> data_;
210 EventFd notify_{0, EFD_NONBLOCK};
211 static_assert(
static_cast<int>(Priority::High) == 0);
212 static_assert(
static_cast<int>(Priority::Low) == 1);
214 std::array<TimerQueue, 2> tqs_{tp_, tp_};
215 HookList end_of_cycle_no_wait_hooks, end_of_event_dispatch_hooks_;
216 Micros priority_io_poll_threshold_ = Micros::max();
217 Micros user_hook_poll_threshold_ = Micros::max();
218 WallTime last_time_priority_io_polled_{};
219 WallTime last_time_user_hook_polled_{};
222 bool currently_handling_priority_events_{
false};