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/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() {