|
@@ -170,6 +170,9 @@ typedef struct pending_log_message_t {
|
|
|
/** Log messages waiting to be replayed onto callback-based logs */
|
|
|
static smartlist_t *pending_cb_messages = NULL;
|
|
|
|
|
|
+/** Callback to invoke when pending_cb_messages becomes nonempty. */
|
|
|
+static pending_callback_callback pending_cb_cb = NULL;
|
|
|
+
|
|
|
/** Log messages waiting to be replayed once the logging system is initialized.
|
|
|
*/
|
|
|
static smartlist_t *pending_startup_messages = NULL;
|
|
@@ -538,6 +541,9 @@ logfile_deliver(logfile_t *lf, const char *buf, size_t msg_len,
|
|
|
smartlist_add(pending_cb_messages,
|
|
|
pending_log_message_new(severity,domain,NULL,msg_after_prefix));
|
|
|
*callbacks_deferred = 1;
|
|
|
+ if (smartlist_len(pending_cb_messages) == 1 && pending_cb_cb) {
|
|
|
+ pending_cb_cb();
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
lf->callback(severity, domain, msg_after_prefix);
|
|
@@ -825,6 +831,7 @@ logs_free_all(void)
|
|
|
logfiles = NULL;
|
|
|
messages = pending_cb_messages;
|
|
|
pending_cb_messages = NULL;
|
|
|
+ pending_cb_cb = NULL;
|
|
|
messages2 = pending_startup_messages;
|
|
|
pending_startup_messages = NULL;
|
|
|
UNLOCK_LOGS();
|
|
@@ -987,6 +994,24 @@ add_temp_log(int min_severity)
|
|
|
UNLOCK_LOGS();
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * Register "cb" as the callback to call when there are new pending log
|
|
|
+ * callbacks to be flushed with flush_pending_log_callbacks().
|
|
|
+ *
|
|
|
+ * Note that this callback, if present, can be invoked from any thread.
|
|
|
+ *
|
|
|
+ * This callback must not log.
|
|
|
+ *
|
|
|
+ * It is intentional that this function contains the name "callback" twice: it
|
|
|
+ * sets a "callback" to be called on the condition that there is a "pending
|
|
|
+ * callback".
|
|
|
+ **/
|
|
|
+void
|
|
|
+logs_set_pending_callback_callback(pending_callback_callback cb)
|
|
|
+{
|
|
|
+ pending_cb_cb = cb;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* Add a log handler to send messages in <b>severity</b>
|
|
|
* to the function <b>cb</b>.
|