]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Add a mechanism for the logging system to report queued callbacks
authorNick Mathewson <nickm@torproject.org>
Tue, 1 May 2018 14:05:22 +0000 (10:05 -0400)
committerNick Mathewson <nickm@torproject.org>
Tue, 1 May 2018 14:18:49 +0000 (10:18 -0400)
Sometimes the logging system will queue a log message for later.
When it does this, the callback will either get flushed at the next
safe time, or from the second-elapsed callback.

But we're trying to eliminate the second-elapsed callback, so let's
make a way for the log system to tell its users about this.

src/common/log.c
src/common/torlog.h

index 922e9dd38f5087535da8c6034d58078c6d0189b1..ebd50f62d36c889a6bb652c87fde85b04587b5bd 100644 (file)
@@ -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>.
index ac632ff52177dfa040558209252fa3c6586265cb..de389883c07f8180fafff6c9cff1706186dea2c2 100644 (file)
@@ -154,6 +154,8 @@ int add_android_log(const log_severity_list_t *severity,
                     const char *android_identity_tag);
 #endif // HAVE_ANDROID_LOG_H.
 int add_callback_log(const log_severity_list_t *severity, log_callback cb);
+typedef void (*pending_callback_callback)(void);
+void logs_set_pending_callback_callback(pending_callback_callback cb);
 void logs_set_domain_logging(int enabled);
 int get_min_log_level(void);
 void switch_logs_debug(void);