From 7b468d1d908ee8255e5a9646a9a1a42a6049bf6c Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Wed, 25 Mar 2020 15:20:43 +0100 Subject: [PATCH] libdlogutil: put logs into vector before polling Eventually we want the API to return a single log. With poll at the front, it would be done for every log returned, which is unnecessary. Additionally, remove the "poll returned nothing" condition which allowed all buffers to be drained at the same time. It shouldn't be helping much in practice and can be simplified away. The callback is temporarily not allowed to return 1. This will go away in the final version of the API. Change-Id: I4ccb0a613a902484303f651830a946ccc8718130 Signed-off-by: Michal Bloch --- src/libdlogutil/logretrieve.c | 24 ++++++++++++++---------- src/tests/logutil.c | 11 ++++------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/libdlogutil/logretrieve.c b/src/libdlogutil/logretrieve.c index 43067c7..038a75b 100644 --- a/src/libdlogutil/logretrieve.c +++ b/src/libdlogutil/logretrieve.c @@ -122,7 +122,7 @@ struct fd_info *find_earliest_log(struct fd_info **data_fds, int fd_count, dlogu return best_fdi; } -int put_logs_into_vector(struct fd_info **data_fds, int fd_count, int nfds, struct sort_vector *logs, dlogutil_entry_cb callback, void *userdata, dlogutil_filter_options_s *filter) +int put_logs_into_vector(struct fd_info **data_fds, int fd_count, struct sort_vector *logs, dlogutil_entry_cb callback, void *userdata, dlogutil_filter_options_s *filter) { assert(data_fds); assert(logs); @@ -132,7 +132,7 @@ int put_logs_into_vector(struct fd_info **data_fds, int fd_count, int nfds, stru do { best_fdi = find_earliest_log(data_fds, fd_count, logs->sort_by); if (!best_fdi) - break; + return 1; dlogutil_entry_s *entry; int r = fdi_push_log(best_fdi, logs, &entry, filter); @@ -144,7 +144,7 @@ int put_logs_into_vector(struct fd_info **data_fds, int fd_count, int nfds, stru if (r) return r; } - } while (!nfds || best_fdi->ops->has_log(best_fdi)); // if a buffer got drained and there are still logs incoming, break to give it a chance to refill + } while (best_fdi->ops->has_log(best_fdi)); // if a buffer got drained, break to give them all a chance to refill return 0; } @@ -256,6 +256,11 @@ int do_print(dlogutil_state_s *state) state->flush_target = LONG_MAX; } + int r = put_logs_into_vector(state->data_fds, state->fd_count, &state->logs, state->callback, state->userdata, state->filter_object); + bool const buffers_emptied = (r == 1); + if (r != 0 && r != 1) + return r; + int nfds = TEMP_FAILURE_RETRY(epoll_wait(state->epollfd, state->evs, state->epoll_cnt, 100)); if (nfds < 0) return -errno; @@ -271,10 +276,6 @@ int do_print(dlogutil_state_s *state) } } - int r = put_logs_into_vector(state->data_fds, state->fd_count, nfds, &state->logs, state->callback, state->userdata, state->filter_object); - if (r != 0) - return r; - /* The oldest log can be so fresh as to be from the future * (i.e. has a negative age). This can happen when somebody * changes the realtime clock backwards. In that case let @@ -284,7 +285,7 @@ int do_print(dlogutil_state_s *state) * the clock reaches its old value again. */ const long last_log_age = sort_vector_time_span(&state->logs); const bool is_from_future = (last_log_age < 0); - if (state->logs.dump == DLOGUTIL_MODE_CONTINUOUS && (!nfds || (state->logs.old_logs_dumped == 1 && (last_log_age > state->logs.timeout || is_from_future)))) { + if (state->logs.dump == DLOGUTIL_MODE_CONTINUOUS && (buffers_emptied || (state->logs.old_logs_dumped == 1 && (last_log_age > state->logs.timeout || is_from_future)))) { if (is_from_future) state->flush_target = -1; else { @@ -307,8 +308,11 @@ int do_print(dlogutil_state_s *state) } } - int r = put_logs_into_vector(state->data_fds, state->fd_count, 0, &state->logs, state->callback, state->userdata, state->filter_object); - if (r != 0) + int r; + do + r = put_logs_into_vector(state->data_fds, state->fd_count, &state->logs, state->callback, state->userdata, state->filter_object); + while (r == 0); + if (r != 1) return r; if (state->logs.dump != DLOGUTIL_MODE_CONTINUOUS && state->logs.dump != DLOGUTIL_MAX_DUMP_SIZE) diff --git a/src/tests/logutil.c b/src/tests/logutil.c index 4d49ef7..21fdf65 100644 --- a/src/tests/logutil.c +++ b/src/tests/logutil.c @@ -8,7 +8,7 @@ bool process_log(const dlogutil_entry_s *e, struct timespec reference_ts, dlogutil_sorting_order_e stamp_type, dlogutil_entry_cb callback, void *userdata, long timeout, int *callback_ret); struct fd_info *find_earliest_log(struct fd_info **data_fds, int fd_count, dlogutil_sorting_order_e sort_by); -int put_logs_into_vector(struct fd_info **data_fds, int fd_count, int nfds, struct sort_vector *logs, dlogutil_entry_cb callback, void *userdata, dlogutil_filter_options_s *filter); +int put_logs_into_vector(struct fd_info **data_fds, int fd_count, struct sort_vector *logs, dlogutil_entry_cb callback, void *userdata, dlogutil_filter_options_s *filter); int written_logs = 0; bool free_entries = false; @@ -155,17 +155,14 @@ int main() while (!sort_vector_empty(&sv)) sort_vector_pop(&sv); - assert(put_logs_into_vector(fds, 0, 1, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == 0); + assert(put_logs_into_vector(fds, 0, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == 1); fdi_push_log_ret = -EIO; - assert(put_logs_into_vector(fds, 10, 1, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == -EIO); + assert(put_logs_into_vector(fds, 10, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == -EIO); fdi_push_log_ret = 0; - assert(put_logs_into_vector(fds, 10, 1, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == 0); + assert(put_logs_into_vector(fds, 10, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == 0); assert(sort_vector_used_size(&sv) == 1); - assert(put_logs_into_vector(fds, 10, 0, &sv, callback, (void *)0xDDD, (dlogutil_filter_options_s *)0xEEE) == 0); - assert(sort_vector_used_size(&sv) == 7); - sort_vector_free(&sv); } -- 2.7.4