Store logging streams in a manually linked list instead of std::list
LogMessage::streams_ is a global and thus should have trivial destructor
Bug: None
Change-Id: Ie6a8029602f50b2bc5bab546ffc0365ef0954024
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/157042
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#29552}
diff --git a/modules/audio_device/audio_device_unittest.cc b/modules/audio_device/audio_device_unittest.cc
index 3e75d76..1b970d5 100644
--- a/modules/audio_device/audio_device_unittest.cc
+++ b/modules/audio_device/audio_device_unittest.cc
@@ -12,6 +12,7 @@
#include <algorithm>
#include <cstring>
+#include <list>
#include <memory>
#include <numeric>
diff --git a/modules/video_capture/windows/sink_filter_ds.cc b/modules/video_capture/windows/sink_filter_ds.cc
index 5e8960c..9019b12 100644
--- a/modules/video_capture/windows/sink_filter_ds.cc
+++ b/modules/video_capture/windows/sink_filter_ds.cc
@@ -14,6 +14,7 @@
#include <initguid.h>
#include <algorithm>
+#include <list>
#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc
index 71e0f4f..158be33 100644
--- a/rtc_base/logging.cc
+++ b/rtc_base/logging.cc
@@ -93,7 +93,8 @@
// Note: we explicitly do not clean this up, because of the uncertain ordering
// of destructors at program exit. Let the person who sets the stream trigger
// cleanup by setting to null, or let it leak (safe at program exit).
-LogMessage::StreamList LogMessage::streams_ RTC_GUARDED_BY(g_log_crit);
+ABSL_CONST_INIT LogSink* LogMessage::streams_ RTC_GUARDED_BY(g_log_crit) =
+ nullptr;
// Boolean options default to false (0)
bool LogMessage::thread_, LogMessage::timestamp_;
@@ -201,12 +202,12 @@
}
GlobalLockScope cs(&g_log_crit);
- for (auto& kv : streams_) {
- if (severity_ >= kv.second) {
+ for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
+ if (severity_ >= entry->min_severity_) {
#if defined(WEBRTC_ANDROID)
- kv.first->OnLogMessage(str, severity_, tag_);
+ entry->OnLogMessage(str, severity_, tag_);
#else
- kv.first->OnLogMessage(str, severity_);
+ entry->OnLogMessage(str, severity_);
#endif
}
}
@@ -260,9 +261,9 @@
int LogMessage::GetLogToStream(LogSink* stream) {
GlobalLockScope cs(&g_log_crit);
LoggingSeverity sev = LS_NONE;
- for (auto& kv : streams_) {
- if (!stream || stream == kv.first) {
- sev = std::min(sev, kv.second);
+ for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
+ if (stream == nullptr || stream == entry) {
+ sev = std::min(sev, entry->min_severity_);
}
}
return sev;
@@ -270,15 +271,18 @@
void LogMessage::AddLogToStream(LogSink* stream, LoggingSeverity min_sev) {
GlobalLockScope cs(&g_log_crit);
- streams_.push_back(std::make_pair(stream, min_sev));
+ stream->min_severity_ = min_sev;
+ stream->next_ = streams_;
+ streams_ = stream;
UpdateMinLogSeverity();
}
void LogMessage::RemoveLogToStream(LogSink* stream) {
GlobalLockScope cs(&g_log_crit);
- for (StreamList::iterator it = streams_.begin(); it != streams_.end(); ++it) {
- if (stream == it->first) {
- streams_.erase(it);
+ for (LogSink** entry = &streams_; *entry != nullptr;
+ entry = &(*entry)->next_) {
+ if (*entry == stream) {
+ *entry = (*entry)->next_;
break;
}
}
@@ -337,9 +341,8 @@
void LogMessage::UpdateMinLogSeverity()
RTC_EXCLUSIVE_LOCKS_REQUIRED(g_log_crit) {
LoggingSeverity min_sev = g_dbg_sev;
- for (const auto& kv : streams_) {
- const LoggingSeverity sev = kv.second;
- min_sev = std::min(min_sev, sev);
+ for (LogSink* entry = streams_; entry != nullptr; entry = entry->next_) {
+ min_sev = std::min(min_sev, entry->min_severity_);
}
g_min_sev = min_sev;
}
@@ -445,10 +448,7 @@
// is going to be logged. This introduces unnecessary synchronization for
// a feature that's mostly used for testing.
GlobalLockScope cs(&g_log_crit);
- if (streams_.size() > 0)
- return false;
-
- return true;
+ return streams_ == nullptr;
}
void LogMessage::FinishPrintStream() {
diff --git a/rtc_base/logging.h b/rtc_base/logging.h
index 17c6c24b..1ca6ea8 100644
--- a/rtc_base/logging.h
+++ b/rtc_base/logging.h
@@ -46,7 +46,6 @@
#include <errno.h>
-#include <list>
#include <sstream> // no-presubmit-check TODO(webrtc:8982)
#include <string>
#include <utility>
@@ -99,6 +98,7 @@
ERRCTX_HR = ERRCTX_HRESULT, // LOG_E(sev, HR, x)
};
+class LogMessage;
// Virtual sink interface that can receive log messages.
class LogSink {
public:
@@ -110,6 +110,12 @@
virtual void OnLogMessage(const std::string& message,
LoggingSeverity severity);
virtual void OnLogMessage(const std::string& message) = 0;
+
+ private:
+ friend class ::rtc::LogMessage;
+ // Members for LogMessage class to keep linked list of the registered sinks.
+ LogSink* next_ = nullptr;
+ LoggingSeverity min_severity_;
};
namespace webrtc_logging_impl {
@@ -437,16 +443,15 @@
// Sets whether logs will be directed to stderr in debug mode.
static void SetLogToStderr(bool log_to_stderr);
- // Stream: Any non-blocking stream interface. LogMessage takes ownership of
- // the stream. Multiple streams may be specified by using AddLogToStream.
- // LogToStream is retained for backwards compatibility; when invoked, it
- // will discard any previously set streams and install the specified stream.
- // GetLogToStream gets the severity for the specified stream, of if none
- // is specified, the minimum stream severity.
- // RemoveLogToStream removes the specified stream, without destroying it.
- static int GetLogToStream(LogSink* stream = nullptr);
+ // Stream: Any non-blocking stream interface.
+ // Installs the |stream| to collect logs with severtiy |min_sev| or higher.
+ // |stream| must live until deinstalled by RemoveLogToStream
static void AddLogToStream(LogSink* stream, LoggingSeverity min_sev);
+ // Removes the specified stream, without destroying it.
static void RemoveLogToStream(LogSink* stream);
+ // Returns the severity for the specified stream, of if none is specified,
+ // the minimum stream severity.
+ static int GetLogToStream(LogSink* stream = nullptr);
// Testing against MinLogSeverity allows code to avoid potentially expensive
// logging operations by pre-checking the logging level.
@@ -464,8 +469,6 @@
private:
friend class LogMessageForTesting;
- typedef std::pair<LogSink*, LoggingSeverity> StreamAndSeverity;
- typedef std::list<StreamAndSeverity> StreamList;
// Updates min_sev_ appropriately when debug sinks change.
static void UpdateMinLogSeverity();
@@ -499,7 +502,7 @@
std::string extra_;
// The output streams and their associated severities
- static StreamList streams_;
+ static LogSink* streams_;
// Flags for formatting options
static bool thread_, timestamp_;
diff --git a/sdk/android/native_unittests/audio_device/audio_device_unittest.cc b/sdk/android/native_unittests/audio_device/audio_device_unittest.cc
index da7790c..88dfad4 100644
--- a/sdk/android/native_unittests/audio_device/audio_device_unittest.cc
+++ b/sdk/android/native_unittests/audio_device/audio_device_unittest.cc
@@ -8,6 +8,7 @@
* be found in the AUTHORS file in the root of the source tree.
*/
+#include <list>
#include <memory>
#include <numeric>