From d328ca8488df3d4edecd4b0372d471f1f46a47dc Mon Sep 17 00:00:00 2001 From: Sebastian Reimers Date: Mon, 4 Sep 2023 13:37:27 +0200 Subject: [PATCH] refactor fd_listen and fd_close --- include/re_main.h | 2 +- src/main/main.c | 118 ++++++++++++++++++++++++++------------------ src/mqueue/mqueue.c | 2 +- src/tcp/tcp.c | 6 +-- src/udp/udp.c | 4 +- 5 files changed, 77 insertions(+), 55 deletions(-) diff --git a/include/re_main.h b/include/re_main.h index 5385616d5..db24f9b23 100644 --- a/include/re_main.h +++ b/include/re_main.h @@ -38,7 +38,7 @@ typedef void (re_signal_h)(int sig); int fd_listen(struct re_fhs **fhs, re_sock_t fd, int flags, fd_h *fh, void *arg); -void fd_close(struct re_fhs **fhs); +void *fd_close(struct re_fhs *fhs); int fd_setsize(int maxfds); int libre_init(void); diff --git a/src/main/main.c b/src/main/main.c index 7b1e2c4f4..bb8396067 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -581,7 +581,7 @@ static int poll_setup(struct re *re) * @return 0 if success, otherwise errorcode */ int fd_listen(struct re_fhs **fhsp, re_sock_t fd, int flags, fd_h fh, - void *arg) + void *arg) { struct re *re = re_get(); struct re_fhs *fhs; @@ -592,7 +592,7 @@ int fd_listen(struct re_fhs **fhsp, re_sock_t fd, int flags, fd_h fh, return EINVAL; } - if (!fhsp) + if (!fhsp || !flags || !fh) return EINVAL; #ifndef RELEASE @@ -606,57 +606,36 @@ int fd_listen(struct re_fhs **fhsp, re_sock_t fd, int flags, fd_h fh, return EBADF; } - if (flags || fh) { - err = poll_setup(re); - if (err) - return err; - } + err = poll_setup(re); + if (err) + return err; fhs = *fhsp; - if (!fhs) { fhs = mem_zalloc(sizeof(struct re_fhs), NULL); if (!fhs) return ENOMEM; - fhs->fd = RE_BAD_SOCK; + fhs->fd = fd; fhs->index = -1; - *fhsp = fhs; - } - - DEBUG_INFO("fd_listen: fd=%d flags=0x%02x\n", fd, flags); - - /* allow setting fd only once, new fd needs new fhs allocation */ - if (fhs->fd == RE_BAD_SOCK) - fhs->fd = fd; - - if (fhs->fd != fd) { - DEBUG_WARNING("fd_listen: fhs reuse conflict %d\n", fd); - return EBADF; - } - - /* Update fhs */ - fhs->fh = fh; - fhs->arg = arg; + DEBUG_INFO("fd_listen/new: fd=%d flags=0x%02x\n", fd, flags); - /* Stop listening */ - if (!flags && fhs->flags) { - fhs->fh = NULL; - mbuf_write_ptr(re->fhsld, (intptr_t)fhs); - *fhsp = mem_deref(fhs); - --re->nfds; - } - - /* Start listening */ - if (flags && !fhs->flags) { - /* reference for poll loop - avoid dangling pointer */ - mem_ref(fhs); ++re->nfds; } + else { + if (unlikely(fhs->fd != fd)) { + DEBUG_WARNING("fd_listen: fhs reuse conflict %d\n", + fd); + return EBADF; + } + DEBUG_INFO("fd_listen/update: fd=%d flags=0x%02x\n", fd, + flags); + } - /* Update listening flags */ fhs->flags = flags; + fhs->fh = fh; + fhs->arg = arg; switch (re->method) { #ifdef HAVE_SELECT @@ -677,14 +656,17 @@ int fd_listen(struct re_fhs **fhsp, re_sock_t fd, int flags, fd_h fh, #endif default: + err = ENOTSUP; break; } - if (err && flags) { - fd_close(fhsp); + if (err) { + mem_deref(fhs); DEBUG_WARNING("fd_listen err: fd=%d flags=0x%02x (%m)\n", fd, flags, err); - return err; + } + else { + *fhsp = fhs; } return err; @@ -692,16 +674,56 @@ int fd_listen(struct re_fhs **fhsp, re_sock_t fd, int flags, fd_h fh, /** - * Stop listening for events on a file descriptor + * Stop and destruct listening for events on a file descriptor * - * @param fd File descriptor + * @param fhs File descriptor handler struct pointer + * + * @return always NULL */ -void fd_close(struct re_fhs **fhs) +void *fd_close(struct re_fhs *fhs) { - if (!fhs || !*fhs) - return; + struct re *re = re_get(); + int err = 0; + + if (!fhs || !re) + return NULL; + + fhs->flags = 0; + fhs->fh = NULL; + fhs->arg = NULL; + + switch (re->method) { +#ifdef HAVE_SELECT + case METHOD_SELECT: + err = set_select_fds(re, fhs); + break; +#endif +#ifdef HAVE_EPOLL + case METHOD_EPOLL: + err = set_epoll_fds(re, fhs); + break; +#endif + +#ifdef HAVE_KQUEUE + case METHOD_KQUEUE: + err = set_kqueue_fds(re, fhs); + break; +#endif + + default: + err = ENOTSUP; + break; + } + + if (err) + DEBUG_WARNING("fd_close err: fd=%d (%m)\n", fhs->fd, err); + else + DEBUG_INFO("fd_close: fd=%d\n", fhs->fd); + + mbuf_write_ptr(re->fhsld, (intptr_t)fhs); + --re->nfds; - (void)fd_listen(fhs, (*fhs)->fd, 0, NULL, NULL); + return NULL; } diff --git a/src/mqueue/mqueue.c b/src/mqueue/mqueue.c index 887f18edd..214c0c94c 100644 --- a/src/mqueue/mqueue.c +++ b/src/mqueue/mqueue.c @@ -51,7 +51,7 @@ static void destructor(void *arg) struct mqueue *q = arg; if (q->pfd[0] != RE_BAD_SOCK) { - fd_close(&q->fhs); + q->fhs = fd_close(q->fhs); (void)close(q->pfd[0]); } if (q->pfd[1] != RE_BAD_SOCK) diff --git a/src/tcp/tcp.c b/src/tcp/tcp.c index 10aa85a4d..889713e51 100644 --- a/src/tcp/tcp.c +++ b/src/tcp/tcp.c @@ -132,7 +132,7 @@ static void sock_destructor(void *data) struct tcp_sock *ts = data; if (ts->fd != RE_BAD_SOCK) { - fd_close(&ts->fhs); + ts->fhs = fd_close(ts->fhs); (void)close(ts->fd); } if (ts->fdc != RE_BAD_SOCK) @@ -164,7 +164,7 @@ static void conn_destructor(void *data) list_flush(&tc->sendq); if (tc->fdc != RE_BAD_SOCK) { - fd_close(&tc->fhs); + tc->fhs = fd_close(tc->fhs); (void)close(tc->fdc); } } @@ -271,7 +271,7 @@ static void conn_close(struct tcp_conn *tc, int err) /* Stop polling */ if (tc->fdc != RE_BAD_SOCK) { - fd_close(&tc->fhs); + tc->fhs = fd_close(tc->fhs); (void)close(tc->fdc); tc->fdc = RE_BAD_SOCK; } diff --git a/src/udp/udp.c b/src/udp/udp.c index d2838b854..496e7581d 100644 --- a/src/udp/udp.c +++ b/src/udp/udp.c @@ -134,7 +134,7 @@ static void udp_destructor(void *data) #endif if (RE_BAD_SOCK != us->fd) { - fd_close(&us->fhs); + us->fhs = fd_close(us->fhs); (void)close(us->fd); } } @@ -783,7 +783,7 @@ void udp_thread_detach(struct udp_sock *us) return; if (RE_BAD_SOCK != us->fd) - fd_close(&us->fhs); + us->fhs = fd_close(us->fhs); }