]> PatchyGit - patchyircd.git/commitdiff
netpoll: wait for uv_close before reusing polldata
authorEgor <egor@patchysicp.xyz>
Sun, 2 Mar 2025 20:26:20 +0000 (22:26 +0200)
committerEgor <egor@patchysicp.xyz>
Sun, 2 Mar 2025 20:26:20 +0000 (22:26 +0200)
src/netpoll.cpp

index e50ca78..545a969 100644 (file)
@@ -227,14 +227,33 @@ struct polldata {
        uv_poll_t uv;
        int events, revents, fd;
 };
-static polldata uvpollbuf[NETPOLL_MAXFDS] = {};
 static polldata *uvpoll[NETPOLL_MAXFDS] = {};
 static uv_loop_t *uvloop = 0;
 static int 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) {
+                       fprintf(stderr, "uvalloc::get: out of polldata!\n");
+                       abort();
+               }
+               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 net_poll_init(void)
 {
-       for (int i = 0; i < NETPOLL_MAXFDS; i++)
-               uvpoll[i] = &uvpollbuf[i];
+       uvalloc::init();
        uvloop = uv_default_loop();
 }
 void net_poll_fini(void)
@@ -247,7 +266,7 @@ void net_poll_fini(void)
 }
 static void net_poll_add_impl(int i)
 {
-       struct polldata *poll = uvpoll[nfds-1];
+       struct polldata *poll = uvalloc::get();
        memmove(uvpoll+i+1, uvpoll+i, sizeof(uvpoll[0])*(nfds-1-i));
        uvpoll[i] = poll;
        poll->events = 0;
@@ -261,8 +280,9 @@ static void net_poll_del_impl(int i)
 {
        struct polldata *poll = uvpoll[i];
        memmove(uvpoll+i, uvpoll+i+1, sizeof(uvpoll[0])*(nfds-(i+1)));
-       uvpoll[nfds-1] = poll;
-       uv_close((uv_handle_t *)&poll->uv, 0);
+       uv_close((uv_handle_t *)&poll->uv, [](uv_handle_t *handle){
+               uvalloc::put(container_of(handle, struct polldata, uv));
+       });
        if (lastptr > i)
                lastptr--;
 }