From b01f54a004729008c46d77cb95f74bb41395ff04 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 2 Mar 2025 22:26:20 +0200 Subject: [PATCH] netpoll: wait for uv_close before reusing polldata --- src/netpoll.cpp | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/netpoll.cpp b/src/netpoll.cpp index e50ca78..545a969 100644 --- a/src/netpoll.cpp +++ b/src/netpoll.cpp @@ -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(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--; } -- 2.56.0