diff --git a/remoting/protocol/webrtc_event_log_data.cc b/remoting/protocol/webrtc_event_log_data.cc index 322e277359329d..2525eb4ce4cb80 100644 --- a/remoting/protocol/webrtc_event_log_data.cc +++ b/remoting/protocol/webrtc_event_log_data.cc @@ -12,6 +12,7 @@ namespace remoting::protocol { WebrtcEventLogData::WebrtcEventLogData() { + base::AutoLock auto_lock(lock_); // See the caveat for base::circular_deque::reserve(). Calling reserve() is // OK here, since items are never removed until the list reaches its maximum // allowed size. @@ -25,17 +26,20 @@ void WebrtcEventLogData::SetMaxSectionSizeForTest(int max_section_size) { } void WebrtcEventLogData::SetMaxSectionsForTest(int max_sections) { + base::AutoLock auto_lock(lock_); max_sections_ = max_sections; sections_.reserve(max_sections_); } base::circular_deque WebrtcEventLogData::TakeLogData() { + base::AutoLock auto_lock(lock_); auto result = std::move(sections_); - // The |sections_| container is still valid but unspecified. Call Clear() to - // be certain it is empty (and the correct capacity is reserved). - Clear(); + // The |sections_| container is still valid but unspecified. Clear it and + // reserve the correct capacity. + sections_.clear(); + sections_.reserve(max_sections_); return result; } @@ -44,6 +48,7 @@ void WebrtcEventLogData::Write(std::string_view log_event) { LOG(WARNING) << "Oversized RTC log event: size = " << log_event.size(); } + base::AutoLock auto_lock(lock_); if (NeedNewSection(log_event.size())) { CreateNewSection(); } @@ -54,6 +59,7 @@ void WebrtcEventLogData::Write(std::string_view log_event) { } void WebrtcEventLogData::Clear() { + base::AutoLock auto_lock(lock_); sections_.clear(); sections_.reserve(max_sections_); } diff --git a/remoting/protocol/webrtc_event_log_data.h b/remoting/protocol/webrtc_event_log_data.h index 53e2b9ddf0587e..a9e26818a44ed9 100644 --- a/remoting/protocol/webrtc_event_log_data.h +++ b/remoting/protocol/webrtc_event_log_data.h @@ -10,6 +10,8 @@ #include #include "base/containers/circular_deque.h" +#include "base/synchronization/lock.h" +#include "base/thread_annotations.h" namespace remoting::protocol { @@ -50,14 +52,19 @@ class WebrtcEventLogData { private: // Returns true if a new section must be created to store the event. - bool NeedNewSection(size_t log_event_size) const; + bool NeedNewSection(size_t log_event_size) const + EXCLUSIVE_LOCKS_REQUIRED(lock_); // Appends a new section of zero size to the end of the list, removing the // oldest one if necessary. On return, the section at the end (the list's // "back") will be empty, ready to accept the new data. - void CreateNewSection(); + void CreateNewSection() EXCLUSIVE_LOCKS_REQUIRED(lock_); - base::circular_deque sections_; + // Write() is called on the WebRTC "rtc_event_log" task queue (a + // base::ThreadPool sequence in Chromium), while TakeLogData() is called on + // the CRD network thread. |lock_| serializes access to |sections_|. + mutable base::Lock lock_; + base::circular_deque sections_ GUARDED_BY(lock_); // Value chosen to keep the memory-usage within reasonable limits, but also // allow for recording "most" sessions entirely.