dlog_logger daemon: handle epoll dynamically 90/174690/7 accepted/tizen/unified/20180411.065555 submit/tizen/20180410.115257
authorMichal Bloch <m.bloch@samsung.com>
Wed, 4 Apr 2018 13:58:29 +0000 (15:58 +0200)
committersanghyeok oh <sanghyeok.oh@samsung.com>
Tue, 10 Apr 2018 11:50:54 +0000 (11:50 +0000)
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 <m.bloch@samsung.com>
include/logcommon.h
src/logger/logger.c

index 6f3f753..eed909f 100644 (file)
@@ -26,7 +26,6 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/syscall.h>
-#include <queued_entry.h>
 #include <dlog.h>
 #include <fcntl.h>
 
index f784c9b..2ca8c49 100755 (executable)
@@ -34,6 +34,7 @@
 #include <sys/epoll.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
+#include <sys/resource.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/un.h>
@@ -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;