]> PatchyGit - patchyircd.git/commitdiff
netpoll: store pollfds in a vector
authorEgor <egor@patchysicp.xyz>
Thu, 5 Jun 2025 16:54:34 +0000 (19:54 +0300)
committerEgor <egor@patchysicp.xyz>
Thu, 5 Jun 2025 16:54:34 +0000 (19:54 +0300)
src/netpoll.cpp

index c94b511..0ed6939 100644 (file)
@@ -4,6 +4,7 @@
 #include "util.h"
 
 #include <algorithm>
+#include <vector>
 
 namespace netpoll {
 struct pollfd {
@@ -12,8 +13,7 @@ struct pollfd {
        int type;
 };
 #define NETPOLL_MAXFDS 1024
-static struct pollfd fds[NETPOLL_MAXFDS] = {};
-static int nfds = 0;
+static std::vector<pollfd*> fds;
 
 #define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
 struct polldata {
@@ -22,7 +22,7 @@ struct polldata {
 };
 static polldata *uvpoll[NETPOLL_MAXFDS] = {};
 static uv_loop_t *uvloop = 0;
-static int lastptr = 0;
+static size_t lastptr = 0;
 namespace uvalloc {
        static polldata uvpollbuf[NETPOLL_MAXFDS] = {};
        static polldata *freelist = 0;
@@ -71,7 +71,7 @@ static void cb(uv_poll_t *handle, int status, int events)
 }
 void begin(void)
 {
-       for (int i = 0; i < nfds; i++) {
+       for (size_t i = 0; i < fds.size(); i++) {
                if (uvpoll[i]->dead == 0) {
                        uv_poll_start(&uvpoll[i]->uv, uvpoll[i]->events, cb);
                        uvpoll[i]->revents = 0;
@@ -83,60 +83,58 @@ void begin(void)
 }
 bool get(event &out)
 {
-       while (lastptr != nfds && !uvpoll[lastptr]->revents) {
+       while (lastptr != fds.size() && !uvpoll[lastptr]->revents) {
                lastptr++;
        }
-       if (lastptr == nfds)
+       if (lastptr == fds.size())
                return false;
-       pollfd &pfd = fds[lastptr];
-       out.assoc = pfd.assoc;
-       out.fd = pfd.fd;
-       out.type = pfd.type;
+       pollfd *pfd = fds[lastptr];
+       out.assoc = pfd->assoc;
+       out.fd = pfd->fd;
+       out.type = pfd->type;
        out.revents = uvpoll[lastptr]->revents;
        lastptr++;
        return true;
 }
 
-static int search(SOCKET fd, bool add) {
+static size_t search(SOCKET fd, bool add) {
        if (fd == INVALID_SOCKET)
                abortf("netpoll::search: INVALID_SOCKET\n");
-       auto it = std::partition_point(fds, fds+nfds, [fd](const auto &p){ return p.fd < fd; });
-       bool found = it != fds+nfds && it->fd == fd;
+       auto it = std::partition_point(fds.begin(), fds.end(), [fd](const auto &p){ return p->fd < fd; });
+       bool found = it != fds.end() && (*it)->fd == fd;
        if (found == add)
                abortf("netpoll::search: duplicate or missing socket\n");
        if (add) {
-               if (nfds == NETPOLL_MAXFDS)
+               if (fds.size() == NETPOLL_MAXFDS)
                        abortf("netpoll::add: NETPOLL_MAXFDS limit\n");
-               memmove(it+1, it, sizeof(fds[0])*(fds+nfds-it));
-               nfds++;
-               *it = pollfd{};
-               it->fd = fd;
+               it = fds.insert(it, new pollfd());
+               (*it)->fd = fd;
        }
-       return it - fds;
+       return it - fds.begin();
 }
 
 void add(SOCKET fd, int type, void *assoc)
 {
-       int i = search(fd, true);
-       fds[i].assoc = assoc;
-       fds[i].type = type;
+       size_t i = search(fd, true);
+       fds[i]->assoc = assoc;
+       fds[i]->type = type;
        struct polldata *poll = uvalloc::get();
-       memmove(uvpoll+i+1, uvpoll+i, sizeof(uvpoll[0])*(nfds-1-i));
+       memmove(uvpoll+i+1, uvpoll+i, sizeof(uvpoll[0])*(fds.size()-1-i));
        uvpoll[i] = poll;
        poll->events = 0;
        poll->revents = 0;
-       poll->fd = fds[i].fd;
+       poll->fd = fds[i]->fd;
        poll->dead = 0;
-       uv_poll_init_socket(uvloop, &poll->uv, fds[i].fd);
+       uv_poll_init_socket(uvloop, &poll->uv, fds[i]->fd);
        if (lastptr >= i)
                lastptr++;
 }
 void del_and_close(SOCKET fd)
 {
-       int i = search(fd, false);
+       size_t i = search(fd, false);
        uvpoll[i]->events = 0;
        struct polldata *poll = uvpoll[i];
-       memmove(uvpoll+i, uvpoll+i+1, sizeof(uvpoll[0])*(nfds-(i+1)));
+       memmove(uvpoll+i, uvpoll+i+1, sizeof(uvpoll[0])*(fds.size()-(i+1)));
        uv_close((uv_handle_t *)&poll->uv, [](uv_handle_t *handle){
                struct polldata *p = container_of(handle, struct polldata, uv);
                closesocket(p->fd);
@@ -144,8 +142,9 @@ void del_and_close(SOCKET fd)
        });
        if (lastptr > i)
                lastptr--;
-       memmove(fds+i, fds+i+1, sizeof(fds[0])*(nfds-(i+1)));
-       nfds--;
+
+       delete fds[i];
+       fds.erase(fds.begin()+i);
 }
 void reg(SOCKET fd, int ev)
 {
@@ -153,6 +152,6 @@ void reg(SOCKET fd, int ev)
 }
 void change_type(SOCKET fd, int type)
 {
-       fds[search(fd, false)].type = type;
+       fds[search(fd, false)]->type = type;
 }
 }