From f40fa3e0296c5b7c4b0f3467c6c690e334fd7b08 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Fri, 13 Jan 2023 21:08:28 +0100 Subject: [PATCH] dlog_logger: cull unused logger readers This will avoid unnecessary resource usage, in particular needless threads when the transition happens. Change-Id: Ia2a057b964f1ab0e9cefc582214495d37984ed4c --- src/logger/logger.c | 59 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/src/logger/logger.c b/src/logger/logger.c index e219644..d95bc7c 100644 --- a/src/logger/logger.c +++ b/src/logger/logger.c @@ -243,6 +243,11 @@ int add_reader_memory(struct logger *server, struct reader_memory *reader) return 0; } +#ifndef UNIT_TEST +/* This really belongs to the UNIT_TEST block at the bottom since it is only used + * by a function living there, but has not been moved there to keep patches small + * and because this function is going to be removed soon in an upcoming patch. */ + static int add_reader_logger(struct logger *server, struct reader_logger *reader) { assert(reader); @@ -271,6 +276,7 @@ failure: return ret; } +#endif int create_fifo_fds(struct logger *server, int pipe_fd[2], int flags, bool dump) { @@ -733,13 +739,16 @@ int logger_create(struct logger_config_data *data, struct logger *l) if (qos_is_enabled(&l->qos)) { r = reader_add_subreader_metrics(&g_backend.logger_readers[id]->common, &l->qos); - if (r < 0) + if (r < 0) { + reader_free(&g_backend.logger_readers[id]->common); + g_backend.logger_readers[id] = NULL; return r; + } } - r = add_reader_logger(l, g_backend.logger_readers[id]); - if (r < 0) - return r; + /* The reader is not yet complete; later in `finalize_init` + * it will receive further readers and be added to epoll + * or alternatively get culled if it gets no sub-readers. */ } for (log_id_t id = 0; id < LOG_ID_MAX; id++) @@ -1325,6 +1334,29 @@ static int finalize_init(struct logger_config_data *data, struct logger *server) .data = data, }, parse_logfile_config); + /* The above created subs for logger readers. + * There is no way for them to gain more at + * runtime, so this is the time to do some + * processing that relies on subs being ready. */ + for (log_id_t id = 0; id < LOG_ID_MAX; ++id) { + struct reader_logger *const reader = g_backend.logger_readers[id]; + if (!reader) + continue; + + if (reader->common.subs == NULL) { + reader_free(&reader->common); + g_backend.logger_readers[id] = NULL; + continue; + } + + r = add_reader_logger(server, reader); + if (r < 0) { + reader_free(&reader->common); + g_backend.logger_readers[id] = NULL; + return r; + } + } + return 0; } @@ -1347,15 +1379,16 @@ bool early_termination(const struct logger_config_data *data, const struct logge /* In order to check if the deamon will be doing nothing * and can quit instantaneously, we do three checks: */ - /* 1. We make sure that there are no logger subreaders. - * When the logger backend is being used, the daemon reads the data - * in order to use it internally. The daemon always reads each buffer - * to a separate reader and each concrete usage has its own subreader. - * Therefore, we need to check if no subreaders exist. */ - for (list_head l = logger->readers_logger; l != NULL; list_next(&l)) { - struct reader_logger *reader = list_at(l); - if (reader->common.subs != NULL) - return false; + /* 1. We make sure that there are no Android Logger readers. + * Note that an earlier function gets rid of any readers that + * don't do anything (i.e. have no subs and no way to get them). */ + for (log_id_t id = 0; id < LOG_ID_MAX; ++id) { + const struct reader_logger *const reader = g_backend.logger_readers[id]; + if (!reader) + continue; + + assert(reader->common.subs != NULL); + return false; } /* 2. We make sure that no pipe-like buffer is enabled. -- 2.7.4