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
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.
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);
}
}
}
}
-
// 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 <typename T> 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
{
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);
}
}
}
// TODO use buffer
if (log_current_line) {
if (log_to_console) {
- std::cout << msg;
+ do_log_part(msg);
}
}
}
// 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();
}
}
}
//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);
// Process events until all services have terminated.
while (service_set->count_active_services() != 0) {
- // ev_loop(loop, EVLOOP_ONESHOT);
eventLoop.run();
}
}
}
+ while (! is_log_flushed()) {
+ eventLoop.run();
+ }
+
close_control_socket(&eventLoop);
if (am_system_init) {