From ca8d273dbb0709867d5e657c43ca16c4fe2036de Mon Sep 17 00:00:00 2001 From: Davin McCall Date: Sun, 5 Jun 2016 21:05:40 +0100 Subject: [PATCH] Make all log messages go via the log buffer. Flush the log buffer before exit. --- src/cpbuffer.h | 6 ++++++ src/dinit-log.cc | 44 +++++++++++++++++++++++++++++++++++++++----- src/dinit-log.h | 1 + src/dinit.cc | 17 ++++------------- 4 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/cpbuffer.h b/src/cpbuffer.h index 9787204..1c05174 100644 --- a/src/cpbuffer.h +++ b/src/cpbuffer.h @@ -66,6 +66,12 @@ template class CPBuffer return 1; } + // Trim the buffer to the specified length (must be less than current length) + void trim_to(int new_length) + { + length = new_length; + } + char operator[](int idx) noexcept { int dest_idx = cur_idx + idx; diff --git a/src/dinit-log.cc b/src/dinit-log.cc index 8dd08c6..5d79971 100644 --- a/src/dinit-log.cc +++ b/src/dinit-log.cc @@ -17,6 +17,7 @@ extern EventLoop_t eventLoop; LogLevel log_level = LogLevel::WARN; LogLevel cons_log_level = LogLevel::WARN; + static bool log_to_console = false; // whether we should output log messages to // console immediately static bool log_current_line; // Whether the current line is being logged @@ -179,6 +180,11 @@ void init_log(ServiceSet *sset) noexcept enable_console_log(true); } +bool is_log_flushed() noexcept +{ + return log_stream[DLOG_CONS].current_index > 0; +} + // Enable or disable console logging. If disabled, console logging will be disabled on the // completion of output of the current message (if any), at which point the first service record // queued in the service set will acquire the console. @@ -236,7 +242,6 @@ template static void do_log(T ... args) noexcept bool was_first = (log_stream[DLOG_CONS].current_index == 0); log_stream[DLOG_CONS].current_index += amount; if (was_first && log_to_console) { - //ev_io_start(ev_default_loop(EVFLAG_AUTO), & log_stream[DLOG_CONS].eviocb); log_stream[DLOG_CONS].registerWith(&eventLoop, log_stream[DLOG_CONS].fd, out_events); } } @@ -253,13 +258,39 @@ template static void do_log(LogLevel lvl, T ... args) noexcept } } - // Log a message. A newline will be appended. void log(LogLevel lvl, const char *msg) noexcept { do_log(lvl, "dinit: ", msg, "\n"); } +// Log part of a message. A series of calls to do_log_part must be followed by a call to do_log_commit. +template static void do_log_part(T arg) noexcept +{ + int amount = sum_length(arg); + if (log_stream[DLOG_CONS].log_buffer.get_free() >= amount) { + append(log_stream[DLOG_CONS].log_buffer, arg); + } + else { + // reset + log_stream[DLOG_CONS].log_buffer.trim_to(log_stream[DLOG_CONS].current_index); + log_current_line = false; + // TODO mark discarded message + } +} + +// Commit a message that was issued as a series of parts (via do_log_part). +static void do_log_commit() noexcept +{ + if (log_current_line) { + bool was_first = log_stream[DLOG_CONS].current_index == 0; + log_stream[DLOG_CONS].current_index = log_stream[DLOG_CONS].log_buffer.get_length(); + if (was_first && log_to_console) { + log_stream[DLOG_CONS].registerWith(&eventLoop, log_stream[DLOG_CONS].fd, out_events); + } + } +} + // Log a multi-part message beginning void logMsgBegin(LogLevel lvl, const char *msg) noexcept { @@ -267,7 +298,8 @@ void logMsgBegin(LogLevel lvl, const char *msg) noexcept log_current_line = lvl >= log_level; if (log_current_line) { if (log_to_console) { - std::cout << "dinit: " << msg; + do_log_part("dinit: "); + do_log_part(msg); } } } @@ -278,7 +310,7 @@ void logMsgPart(const char *msg) noexcept // TODO use buffer if (log_current_line) { if (log_to_console) { - std::cout << msg; + do_log_part(msg); } } } @@ -289,7 +321,9 @@ void logMsgEnd(const char *msg) noexcept // TODO use buffer if (log_current_line) { if (log_to_console) { - std::cout << msg << std::endl; + do_log_part(msg); + do_log_part("\n"); + do_log_commit(); } } } diff --git a/src/dinit-log.h b/src/dinit-log.h index d51bf08..2ba474f 100644 --- a/src/dinit-log.h +++ b/src/dinit-log.h @@ -20,6 +20,7 @@ enum class LogLevel { extern LogLevel log_level; void enable_console_log(bool do_enable) noexcept; void init_log(ServiceSet *sset) noexcept; +bool is_log_flushed() noexcept; void log(LogLevel lvl, const char *msg) noexcept; void logMsgBegin(LogLevel lvl, const char *msg) noexcept; diff --git a/src/dinit.cc b/src/dinit.cc index a0e7a5f..8315af1 100644 --- a/src/dinit.cc +++ b/src/dinit.cc @@ -303,36 +303,24 @@ int main(int argc, char **argv) //ev_signal sigint_ev_signal; CallbackSignalHandler sigint_watcher; if (am_system_init) { - //ev_signal_init(&sigint_ev_signal, sigint_reboot_cb, SIGINT); sigint_watcher.setCbFunc(sigint_reboot_cb); } else { - //ev_signal_init(&sigint_ev_signal, sigterm_cb, SIGINT); sigint_watcher.setCbFunc(sigterm_cb); } - //ev_signal sigquit_ev_signal; CallbackSignalHandler sigquit_watcher; if (am_system_init) { // PID 1: SIGQUIT exec's shutdown - //ev_signal_init(&sigquit_ev_signal, sigquit_cb, SIGQUIT); sigquit_watcher.setCbFunc(sigquit_cb); } else { // Otherwise: SIGQUIT terminates dinit - //ev_signal_init(&sigquit_ev_signal, sigterm_cb, SIGQUIT); sigquit_watcher.setCbFunc(sigterm_cb); } - //ev_signal sigterm_ev_signal; - //ev_signal_init(&sigterm_ev_signal, sigterm_cb, SIGTERM); auto sigterm_watcher = CallbackSignalHandler(sigterm_cb); - /* Set up libev */ - //struct ev_loop *loop = ev_default_loop(EVFLAG_AUTO /* | EVFLAG_SIGNALFD */); - //ev_signal_start(loop, &sigint_ev_signal); - //ev_signal_start(loop, &sigquit_ev_signal); - //ev_signal_start(loop, &sigterm_ev_signal); sigint_watcher.registerWatch(&eventLoop, SIGINT); sigquit_watcher.registerWatch(&eventLoop, SIGQUIT); sigterm_watcher.registerWatch(&eventLoop, SIGTERM); @@ -375,7 +363,6 @@ int main(int argc, char **argv) // Process events until all services have terminated. while (service_set->count_active_services() != 0) { - // ev_loop(loop, EVLOOP_ONESHOT); eventLoop.run(); } @@ -398,6 +385,10 @@ int main(int argc, char **argv) } } + while (! is_log_flushed()) { + eventLoop.run(); + } + close_control_socket(&eventLoop); if (am_system_init) { -- 2.25.1