diff --git a/modules/audio_device/audio_device_unittest.cc b/modules/audio_device/audio_device_unittest.cc index 3e75d7624d..1b970d5dad 100644 --- a/modules/audio_device/audio_device_unittest.cc +++ b/modules/audio_device/audio_device_unittest.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include diff --git a/modules/video_capture/windows/sink_filter_ds.cc b/modules/video_capture/windows/sink_filter_ds.cc index 5e8960cc45..9019b127cf 100644 --- a/modules/video_capture/windows/sink_filter_ds.cc +++ b/modules/video_capture/windows/sink_filter_ds.cc @@ -14,6 +14,7 @@ #include #include +#include #include "rtc_base/arraysize.h" #include "rtc_base/checks.h" diff --git a/rtc_base/logging.cc b/rtc_base/logging.cc index 71e0f4f693..158be33b4d 100644 --- a/rtc_base/logging.cc +++ b/rtc_base/logging.cc @@ -93,7 +93,8 @@ bool LogMessage::log_to_stderr_ = true; // 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 @@ LogMessage::~LogMessage() { } 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 @@ void LogMessage::SetLogToStderr(bool log_to_stderr) { 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 @@ int LogMessage::GetLogToStream(LogSink* stream) { 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::ConfigureLogging(const char* params) { 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 @@ bool LogMessage::IsNoop(LoggingSeverity severity) { // 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 17c6c24bf7..1ca6ea8ade 100644 --- a/rtc_base/logging.h +++ b/rtc_base/logging.h @@ -46,7 +46,6 @@ #include -#include #include // no-presubmit-check TODO(webrtc:8982) #include #include @@ -99,6 +98,7 @@ enum LogErrorContext { 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 @@ class LogSink { 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 @@ class LogMessage { // 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 @@ class LogMessage { private: friend class LogMessageForTesting; - typedef std::pair StreamAndSeverity; - typedef std::list StreamList; // Updates min_sev_ appropriately when debug sinks change. static void UpdateMinLogSeverity(); @@ -499,7 +502,7 @@ class LogMessage { 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 da7790c0a0..88dfad4a88 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 #include #include