Мониторинг с несколькими дескрипторами + новый модуль depoll

This commit is contained in:
Alexander Zhirov 2025-08-29 00:35:45 +03:00
parent cb3f40deee
commit 7858416df9
Signed by: alexander
GPG key ID: C8D8BE544A27C511
2 changed files with 285 additions and 50 deletions

73
source/depoll.d Normal file
View file

@ -0,0 +1,73 @@
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_;
}
}