]> PatchyGit - patchyircd.git/commitdiff
netpoll: merge pollfd and polldata structures
authorEgor <egor@patchysicp.xyz>
Thu, 5 Jun 2025 17:34:14 +0000 (20:34 +0300)
committerEgor <egor@patchysicp.xyz>
Thu, 5 Jun 2025 17:34:14 +0000 (20:34 +0300)
src/netpoll.cpp
src/netpoll.h

index 0ed6939..ba6abd6 100644 (file)
@@ -6,45 +6,22 @@
 #include <algorithm>
 #include <vector>
 
+#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
+
 namespace netpoll {
 struct pollfd {
        void *assoc;
-       SOCKET fd;
-       int type;
+       uv_os_sock_t fd;
+       int type, revents, events;
+       bool dead;
+       uv_poll_t handle;
 };
-#define NETPOLL_MAXFDS 1024
 static std::vector<pollfd*> fds;
+static size_t lastptr = 0;
 
-#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member)))
-struct polldata {
-       uv_poll_t uv;
-       int events, revents, fd, dead;
-};
-static polldata *uvpoll[NETPOLL_MAXFDS] = {};
 static uv_loop_t *uvloop = 0;
-static size_t lastptr = 0;
-namespace uvalloc {
-       static polldata uvpollbuf[NETPOLL_MAXFDS] = {};
-       static polldata *freelist = 0;
-       static polldata *get() {
-               polldata *p = freelist;
-               freelist = static_cast<polldata *>(p->uv.data);
-               if (!p)
-                       abortf("uvalloc::get: out of polldata!\n");
-               return p;
-       }
-       static void put(polldata *p) {
-               p->uv.data = freelist;
-               freelist = p;
-       }
-       static void init() {
-               for (int i = NETPOLL_MAXFDS-1; i >= 0; i--)
-                       put(&uvpollbuf[i]);
-       }
-}
 void init(void)
 {
-       uvalloc::init();
        uvloop = uv_default_loop();
 }
 void fini(void)
@@ -57,33 +34,34 @@ void fini(void)
 }
 static void cb(uv_poll_t *handle, int status, int events)
 {
-       struct polldata *poll = container_of(handle, struct polldata, uv);
+       pollfd *pfd = container_of(handle, pollfd, handle);
        if (status == 0) {
-               poll->revents = events;
+               pfd->revents = events;
        }
        uv_poll_stop(handle);
        if (status == -EBADF) {
-               fprintf(stderr, "netpoll::cb: %d EBADF!\n", poll->fd);
-               poll->dead = 1;
-               poll->revents = poll->events & (UV_READABLE | UV_WRITABLE);
+               fprintf(stderr, "netpoll::cb: %d EBADF!\n", pfd->fd);
+               pfd->dead = true;
+               pfd->revents = pfd->events;
        }
        lastptr = 0;
 }
 void begin(void)
 {
-       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;
+       for (pollfd *pfd : fds) {
+               if (!pfd->dead) {
+                       uv_poll_start(&pfd->handle, pfd->events, cb);
+                       pfd->revents = 0;
                } else {
-                       uvpoll[i]->revents = uvpoll[i]->events & (UV_READABLE | UV_WRITABLE);
+                       pfd->revents = pfd->events;
+                       lastptr = 0;
                }
        }
        uv_run(uvloop, UV_RUN_ONCE);
 }
 bool get(event &out)
 {
-       while (lastptr != fds.size() && !uvpoll[lastptr]->revents) {
+       while (lastptr != fds.size() && !fds[lastptr]->revents) {
                lastptr++;
        }
        if (lastptr == fds.size())
@@ -92,12 +70,13 @@ bool get(event &out)
        out.assoc = pfd->assoc;
        out.fd = pfd->fd;
        out.type = pfd->type;
-       out.revents = uvpoll[lastptr]->revents;
+       out.revents = pfd->revents;
        lastptr++;
        return true;
 }
 
-static size_t search(SOCKET fd, bool add) {
+static std::vector<pollfd*>::iterator search(uv_os_sock_t fd, bool add=false)
+{
        if (fd == INVALID_SOCKET)
                abortf("netpoll::search: INVALID_SOCKET\n");
        auto it = std::partition_point(fds.begin(), fds.end(), [fd](const auto &p){ return p->fd < fd; });
@@ -105,53 +84,41 @@ static size_t search(SOCKET fd, bool add) {
        if (found == add)
                abortf("netpoll::search: duplicate or missing socket\n");
        if (add) {
-               if (fds.size() == NETPOLL_MAXFDS)
-                       abortf("netpoll::add: NETPOLL_MAXFDS limit\n");
+               lastptr += int(lastptr >= size_t(it - fds.begin()));
                it = fds.insert(it, new pollfd());
                (*it)->fd = fd;
        }
-       return it - fds.begin();
+       return it;
 }
 
-void add(SOCKET fd, int type, void *assoc)
+void add(uv_os_sock_t fd, int type, void *assoc)
 {
-       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])*(fds.size()-1-i));
-       uvpoll[i] = poll;
-       poll->events = 0;
-       poll->revents = 0;
-       poll->fd = fds[i]->fd;
-       poll->dead = 0;
-       uv_poll_init_socket(uvloop, &poll->uv, fds[i]->fd);
-       if (lastptr >= i)
-               lastptr++;
+       pollfd *pfd = *search(fd, true);
+       pfd->assoc = assoc;
+       pfd->type = type;
+       uv_poll_init_socket(uvloop, &pfd->handle, pfd->fd);
 }
-void del_and_close(SOCKET fd)
+void del_and_close(uv_os_sock_t fd)
 {
-       size_t i = search(fd, false);
-       uvpoll[i]->events = 0;
-       struct polldata *poll = uvpoll[i];
-       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);
-               uvalloc::put(p);
+       auto it = search(fd);
+       pollfd *pfd = *it;
+       uv_close((uv_handle_t *)&pfd->handle, [](uv_handle_t *handle){
+               pollfd *pfd = container_of(handle, pollfd, handle);
+               closesocket(pfd->fd);
+               delete pfd;
        });
-       if (lastptr > i)
-               lastptr--;
 
-       delete fds[i];
-       fds.erase(fds.begin()+i);
+       lastptr -= int(lastptr > size_t(it - fds.begin()));
+       it = fds.erase(it);
 }
-void reg(SOCKET fd, int ev)
+void reg(uv_os_sock_t fd, int ev)
 {
-       uvpoll[search(fd, false)]->events = ev & (UV_READABLE | UV_WRITABLE);
+       pollfd *pfd = *search(fd);
+       pfd->events = ev & (UV_READABLE | UV_WRITABLE);
 }
-void change_type(SOCKET fd, int type)
+void change_type(uv_os_sock_t fd, int type)
 {
-       fds[search(fd, false)]->type = type;
+       pollfd *pfd = *search(fd);
+       pfd->type = type;
 }
 }
index cc38c14..c8e3649 100644 (file)
@@ -7,15 +7,15 @@
 namespace netpoll {
 struct event {
        void *assoc;
-       SOCKET fd;
+       uv_os_sock_t fd;
        int type, revents;
 };
 void init(void);
 void fini(void);
-void add(SOCKET fd, int type, void *assoc);
-void del_and_close(SOCKET fd);
-void reg(SOCKET fd, int ev);
-void change_type(SOCKET fd, int type);
+void add(uv_os_sock_t fd, int type, void *assoc);
+void del_and_close(uv_os_sock_t fd);
+void reg(uv_os_sock_t fd, int ev);
+void change_type(uv_os_sock_t fd, int type);
 void begin(void);
 bool get(event &out);
 }