File size: 1,602 Bytes
f86fb3b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | #pragma once
#include <cstdint>
#include <functional>
#include <vector>
#include <memory>
#include "../core/cache_line.hpp"
namespace quant::gateway {
enum class IOEvent : uint8_t {
READ = 1 << 0,
WRITE = 1 << 1,
ERROR = 1 << 2,
HANGUP = 1 << 3
};
inline IOEvent operator|(IOEvent a, IOEvent b) {
return static_cast<IOEvent>(static_cast<uint8_t>(a) | static_cast<uint8_t>(b));
}
inline bool operator&(IOEvent a, IOEvent b) {
return (static_cast<uint8_t>(a) & static_cast<uint8_t>(b)) != 0;
}
using EventCallback = std::function<void(int fd, IOEvent events)>;
/**
* Cross-platform Ultra-Low Latency IO Event Demultiplexer.
* Backends:
* - Linux: Edge-Triggered epoll (EPOLLET)
* - macOS: Native kqueue (EVFILT_READ / EVFILT_WRITE)
*/
class alignas(core::CACHELINE_SIZE) IOReactor {
public:
IOReactor();
~IOReactor();
IOReactor(const IOReactor&) = delete;
IOReactor& operator=(const IOReactor&) = delete;
bool add_socket(int fd, IOEvent events, EventCallback callback);
bool modify_socket(int fd, IOEvent events);
bool remove_socket(int fd);
/**
* Poll ready events and invoke registered callbacks.
* @param timeout_ms 0 for non-blocking poll, -1 for infinite wait
* @return Number of events dispatched
*/
int poll_events(int timeout_ms = 0);
void stop() noexcept { running_ = false; }
[[nodiscard]] bool is_running() const noexcept { return running_; }
private:
int reactor_fd_{-1};
bool running_{true};
struct Impl;
std::unique_ptr<Impl> pimpl_;
};
} // namespace quant::gateway
|