module depoll; import core.sys.linux.epoll; import core.sys.posix.unistd : close; import core.stdc.errno : errno, EINTR; import core.stdc.string : strerror; import std.string : fromStringz; import std.exception : enforce; class Epoll { private int epfd_ = -1; this(int flags = 0) { epfd_ = epoll_create1(flags); enforce(epfd_ >= 0, "epoll_create1: " ~ strerror(errno).fromStringz.idup); } ~this() { if (epfd_ >= 0) { close(epfd_); epfd_ = -1; } } void add(int fd, uint tag, uint events = EPOLLIN | EPOLLERR | EPOLLHUP) { epoll_event ev; ev.events = events; ev.data.u32 = tag; enforce(epoll_ctl(epfd_, EPOLL_CTL_ADD, fd, &ev) == 0, "epoll_ctl ADD: " ~ strerror(errno).fromStringz.idup); } // Опционально: метод для удаления fd void remove(int fd) { enforce(epoll_ctl(epfd_, EPOLL_CTL_DEL, fd, null) == 0, "epoll_ctl DEL: " ~ strerror(errno).fromStringz.idup); } struct Event { uint tag; uint events; } Event[] wait(int maxevents = 16, int timeout = -1) { epoll_event[] evs = new epoll_event[maxevents]; int n = epoll_wait(epfd_, evs.ptr, maxevents, timeout); if (n <= 0) { // Игнорируем EINTR и другие (как в оригинале: continue) return []; } Event[] res; foreach (i; 0 .. n) { res ~= Event(evs[i].data.u32, evs[i].events); } return res; } @property int handle() const { return epfd_; } }