Переход на edge-triggered; устранение жора CPU

This commit is contained in:
lost+skunk 2025-02-08 21:13:13 +03:00
parent ca1662c403
commit 06f9e483c3
2 changed files with 51 additions and 33 deletions

View file

@ -27,6 +27,15 @@ struct Server {
private shared int epfd, sock;
void start(MD...)() { // TODO: реализовать "слушальщика" хрюникс сокетов (AF_UNIX)
// import core.stdc.signal;
// extern(C) void z (int s) nothrow @nogc @system {
// signal(s, SIG_IGN);
// this.epfd.close();
// this.sock.close();
// raise(0);
// }
// signal(SIGINT, &z);
bool ipv6;
for (short i; i < address.length; ++i)
if (address[i] == ':') {ipv6=true;break;}
@ -47,15 +56,22 @@ struct Server {
err(bind(sock, cast(sockaddr*)&sockt, sockt.sizeof), "bind");
}
int hz;
setsockopt(sock,
IPPROTO_TCP, TCP_NODELAY | SO_REUSEADDR | SO_REUSEPORT,
cast(void*)(new int), int.sizeof);
IPPROTO_TCP, SO_REUSEADDR,
cast(void*)hz, int.sizeof);
setsockopt(sock,
IPPROTO_TCP, TCP_NODELAY,
cast(void*)hz, int.sizeof);
// setsockopt(sock,
// IPPROTO_TCP, SO_REUSEPORT,
// cast(void*)hz, int.sizeof);
err(listen(sock, 512), "listen");
serve!MD;
}
void stop() {
void stop() @nogc {
epfd.close();
sock.close();
}
@ -66,7 +82,7 @@ struct Server {
epoll_event[MAX_EVENTS] evts;
ev.data.fd = sock;
ev.events = EPOLLIN | EPOLLEXCLUSIVE;
ev.events = EPOLLIN;
epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev);
for (;;) {
@ -77,23 +93,35 @@ struct Server {
// sockaddr_in addr;
// socklen_t al = sockaddr_in.sizeof;
// ev.data.fd = accept4(sock, cast(sockaddr*)&addr, &al, SOCK_NONBLOCK);
ev.events = EPOLLIN | EPOLLRDHUP | EPOLLET;
ev.data.fd = accept4(sock, null, null, SOCK_NONBLOCK);
epoll_ctl(epfd, EPOLL_CTL_ADD, ev.data.fd, &ev);
// ip = cast(string)inet_ntoa(addr.sin_addr);
}
// if (ev.data.fd == -1) {
if (evts[i].events & EPOLLRDHUP) {
epoll_ctl(epfd, EPOLL_CTL_DEL, fd, null);
close(fd);
break;
}
rd:
ubyte[128] buf;
ubyte[256] buf;
for (;;) { // обработчик запросов
auto rd = recv(fd, cast(void*)buf, buf.sizeof, 0);
if (rd < 1) break;
auto rqst = parseReq(buf);
if (parseAndValidateURL(rqst.path, &rqst)) {
static auto resp = "HTTP/1.1 400 Bad Request\r\nContent-length: 15\r\n\r\n400 Bad Request";
write(fd, cast(void*)resp, resp.length);
continue;
}
static foreach (mm; __traits(allMembers, T)) {
static if (__traits(isStaticFunction, __traits(getMember, T, mm))) {
foreach(attr; __traits(getAttributes, __traits(getMember, T, mm))) {
static if (is(typeof(attr) == Location)) {
parseAndValidateURL(rqst.path, &rqst);
if (rqst.path == attr.path) {
Response rsp;
__traits(getMember, T, mm)(&rsp, &rqst);
@ -123,7 +151,8 @@ struct Server {
}
}
Request parseReq(ubyte[] body) { // TODO: реализовать парсинг заголовков, оформленных хер пойми как
// TODO: реализовать парсинг заголовков, оформленных хер пойми как
Request parseReq(ubyte[] body) {
int prev;
short[] xxx;
Request req;