From 8c3777d80da9e9ec428c37f880d60ac0b239d35a Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Thu, 15 Feb 2018 14:03:49 +0100 Subject: [PATCH] util: minor mainloop refactor Change-Id: Ia02b4866857eb0328eb6a22a53fc2986e6046265 Signed-off-by: Michal Bloch --- src/logutil/logutil.c | 101 +++++++++++++++++--------------------------------- 1 file changed, 35 insertions(+), 66 deletions(-) diff --git a/src/logutil/logutil.c b/src/logutil/logutil.c index 3ad09ff..2f2282e 100755 --- a/src/logutil/logutil.c +++ b/src/logutil/logutil.c @@ -56,32 +56,39 @@ typedef enum action_e { * @brief Process log * @details Processes a raw log and, if it's old enough, prints it * @param[in] e The entry to process - * @param[in] last Last entry in the buffer + * @param[in] ts Reference timestamp * @param[in] l_file Output file metadata * @param[in] timeout Sort timeout in ms - * @param[in] ignore_timeout Whether to print regardless of timeout * @return 1 if the log was old enough, else 0 */ -static int process_log(struct logger_entry *e, struct logger_entry *last, struct log_file *l_file, long timeout, int ignore_timeout) +static int process_log(struct logger_entry *e, struct timespec ts, struct log_file *l_file, long timeout) { assert(e); - assert(last); assert(l_file); - long s = last->sec_recv_mono - e->sec_recv_mono; - long ns = last->nsec_recv_mono - e->nsec_recv_mono; + long s = ts.tv_sec - e->sec_recv_mono; + long ns = ts.tv_nsec - e->nsec_recv_mono; if (ns < 0) { ns += 1000000000; --s; } - if (ignore_timeout || timeout <= (s*1000 + ns/1000000)) { + if (timeout <= (s*1000 + ns/1000000)) { logfile_write_with_rotation(e, l_file); return 1; } else return 0; } +void flush_logs(struct sort_vector *logs, struct log_file *l_file) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + while (!sort_vector_empty(logs) && process_log(sort_vector_back(logs), ts, l_file, logs->timeout)) + sort_vector_pop(logs); +} + /** * @brief Handle input * @details The main loop reading log data @@ -98,15 +105,9 @@ static void do_print(struct fd_info **data_fds, int fd_count, int dump, struct s assert(l_file); int nfds; - int filled = 1; int r; - int accepting_logs = 1; - struct fd_info * fdi; + struct fd_info *fdi = NULL; int pipes = 0; - int looping = 1; - int timeout = dump ? 5 : 100; - int resttime = 0; - int force_flush = 0; int epollfd; struct epoll_event ev = { .events = EPOLLIN }; @@ -125,57 +126,22 @@ static void do_print(struct fd_info **data_fds, int fd_count, int dump, struct s struct fd_info *swap_tmp = data_fds[nfds]; data_fds[nfds--] = data_fds[--fd_count]; data_fds[fd_count] = swap_tmp; // swap non-destructively lest memory leak - if (!dump) - accepting_logs = -1; } } - while (looping) { - if (dump > 0) { - if (!accepting_logs) { - while (sort_vector_used_size(logs) > dump) - sort_vector_pop(logs); - dump = 0; - filled = 0; - } - } else { - int last_printed = logs->begin; - while (!filled && !sort_vector_empty(logs)) - if (process_log(logs->data[logs->begin], - logs->data[(logs->end ?: logs->size) - 1], - l_file, logs->timeout, force_flush)) - sort_vector_pop(logs); - else - break; - if (last_printed == logs->begin && !sort_vector_empty(logs)) { - resttime += timeout; - if (resttime >= logs->timeout) - force_flush = 1; - } else { - resttime = 0; - force_flush = 0; - } - } + while (true) { + if (!fdi && !dump) + flush_logs(logs, l_file); - if (!accepting_logs) { - if (sort_vector_empty(logs)) - break; - else - continue; - } - - filled = 1; - nfds = epoll_wait(epollfd, &ev, 1, timeout); + nfds = epoll_wait(epollfd, &ev, 1, 100); if (nfds > 0) fdi = (struct fd_info*) ev.data.ptr; else if (nfds == 0 && fd_count > 0) fdi = data_fds[fd_count - 1]; + else if (dump) + break; else { - filled = 0; - if (dump && !pipes) { - force_flush = 1; - accepting_logs = 0; - } + fdi = NULL; continue; } @@ -187,24 +153,27 @@ static void do_print(struct fd_info **data_fds, int fd_count, int dump, struct s break; } + while (fdi->ops->has_log(fdi)) + if (fdi_push_log(fdi, logs, l_file)) + break; + if (r == 0 || (dump && fdi->log_len <= 0 && fdi->log_len != UNLIMITED_LOG_LEN)) { if (fdi->ops != &ops_binfile) // HACK epoll_ctl(epollfd, EPOLL_CTL_DEL, fdi->fd, NULL); if (fdi->ops == &ops_pipe && dump) // HACK --pipes; - else if (--fd_count <= 0) { - accepting_logs = 0; - filled = 0; - } - } - - while (fdi->ops->has_log(fdi)) - if (fdi_push_log(fdi, logs, l_file)) { - looping = 0; + else if (--fd_count <= 0) break; - } + } } + + if (dump > 0) + while (sort_vector_used_size(logs) > dump) + sort_vector_pop(logs); + + logs->timeout = 0; + flush_logs(logs, l_file); } int parse_options(int argc, char **argv, struct log_file *l_file, struct sort_vector *logs, int *enabled_buffers, list_head *file_input_names, action_e *action, int *dump, list_head *filters) -- 2.7.4