From 7bba6ceaf662e1eb64444b48a19132cd87fd9d65 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Wed, 4 Apr 2018 15:58:29 +0200 Subject: [PATCH] dlog_logger daemon: handle epoll dynamically The daemon used to have a static array for 1024 FDs (ie. the default file descriptor limit). This was both wasteful in the usual case, as usually this value is not reached, and incorrect otherwise, because this limit can be increased, causing any extra FDs to starve. Change-Id: Ifc61a2cecbfb1b78fcf00abe9655f02147f8316f Signed-off-by: Michal Bloch --- include/logcommon.h | 1 - src/logger/logger.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/include/logcommon.h b/include/logcommon.h index 6f3f753..eed909f 100644 --- a/include/logcommon.h +++ b/include/logcommon.h @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/src/logger/logger.c b/src/logger/logger.c index f784c9b..2ca8c49 100755 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,7 @@ struct buf_params { struct logger { int epollfd; + unsigned epollcnt; list_head writers; list_head extra_readers; struct log_buffer* buffers[LOG_ID_MAX]; @@ -397,7 +399,13 @@ static inline int add_fd_entity(struct logger *logger, struct fd_entity *fd_enti { assert(logger); assert(fd_entity); - return epoll_ctl(logger->epollfd, EPOLL_CTL_ADD, fd_entity->fd, &fd_entity->event) < 0 ? -errno : 0; + + int r = epoll_ctl(logger->epollfd, EPOLL_CTL_ADD, fd_entity->fd, &fd_entity->event); + if (r < 0) + return -errno; + + ++logger->epollcnt; + return 0; } /** @@ -410,8 +418,15 @@ static inline int add_fd_entity(struct logger *logger, struct fd_entity *fd_enti static inline int remove_fd_entity(struct logger *logger, struct fd_entity *fd_entity) { assert(logger); + assert(logger->epollcnt > 0); assert(fd_entity); - return epoll_ctl(logger->epollfd, EPOLL_CTL_DEL, fd_entity->fd, NULL) < 0 ? -errno : 0; + + int r = epoll_ctl(logger->epollfd, EPOLL_CTL_DEL, fd_entity->fd, NULL); + if (r < 0) + return -errno; + + --logger->epollcnt; + return 0; } /** @@ -1760,6 +1775,32 @@ static void handle_signals(int signo) g_logger_run = 0; } +static void ensure_epoll_size(struct epoll_event **events, unsigned *size, unsigned wanted_size) +{ + assert(events); + assert(size); + + if (wanted_size <= *size) + return; + + typeof(*events) temp = realloc(*events, wanted_size * sizeof **events); + if (!temp) + return; + + *events = temp; + *size = wanted_size; +} + +static int initialize_epoll_size(struct epoll_event **events, unsigned *size) +{ + assert(events); + assert(size); + + *size = 16U; + *events = malloc(*size * sizeof **events); + return !*events ? -ENOMEM : 0; +} + /** * @brief Do logging * @details The main logging loop @@ -1768,8 +1809,6 @@ static void handle_signals(int signo) */ static int do_logger(struct logger* server) { - struct epoll_event events[1024]; - struct sigaction action = { .sa_handler = handle_signals, .sa_flags = 0 @@ -1780,8 +1819,15 @@ static int do_logger(struct logger* server) for (unsigned u = 0; u < NELEMS(handled_signals); ++u) sigaction(handled_signals[u], &action, NULL); + unsigned events_size; + struct epoll_event *events; + int r = initialize_epoll_size(&events, &events_size); + if (r < 0) + return r; while (g_logger_run) { - int nfds = epoll_wait(server->epollfd, events, NELEMS(events), 1000); + ensure_epoll_size(&events, &events_size, server->epollcnt); + + int nfds = epoll_wait(server->epollfd, events, events_size, 1000); if (nfds < 0 && errno == EINTR) continue; -- 2.7.4