Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(328)

Unified Diff: webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.cc

Issue 3005153002: Reland of Make RtcEventLogImpl to use a TaskQueue instead of a helper-thread (Closed)
Patch Set: . Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.h ('k') | webrtc/pc/peerconnection.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.cc
diff --git a/webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.cc b/webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.cc
deleted file mode 100644
index a98336fa521ff06eac2225614f0991fa29f1c810..0000000000000000000000000000000000000000
--- a/webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
- *
- * Use of this source code is governed by a BSD-style license
- * that can be found in the LICENSE file in the root of the source
- * tree. An additional intellectual property rights grant can be found
- * in the file PATENTS. All contributing project authors may
- * be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.h"
-
-#include <algorithm>
-
-#include "webrtc/rtc_base/checks.h"
-#include "webrtc/rtc_base/logging.h"
-#include "webrtc/rtc_base/timeutils.h"
-
-#ifdef ENABLE_RTC_EVENT_LOG
-
-namespace webrtc {
-
-namespace {
-const int kEventsInHistory = 10000;
-
-bool IsConfigEvent(const rtclog::Event& event) {
- rtclog::Event_EventType event_type = event.type();
- return event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT ||
- event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT ||
- event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT ||
- event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT;
-}
-} // namespace
-
-// RtcEventLogImpl member functions.
-RtcEventLogHelperThread::RtcEventLogHelperThread(
- SwapQueue<ControlMessage>* message_queue,
- SwapQueue<std::unique_ptr<rtclog::Event>>* event_queue)
- : message_queue_(message_queue),
- event_queue_(event_queue),
- file_(FileWrapper::Create()),
- thread_(&ThreadOutputFunction, this, "RtcEventLog thread"),
- max_size_bytes_(std::numeric_limits<int64_t>::max()),
- written_bytes_(0),
- start_time_(0),
- stop_time_(std::numeric_limits<int64_t>::max()),
- has_recent_event_(false),
- wake_periodically_(false, false),
- wake_from_hibernation_(false, false),
- file_finished_(false, false) {
- RTC_DCHECK(message_queue_);
- RTC_DCHECK(event_queue_);
- thread_.Start();
-}
-
-RtcEventLogHelperThread::~RtcEventLogHelperThread() {
- ControlMessage message;
- message.message_type = ControlMessage::TERMINATE_THREAD;
- message.stop_time = rtc::TimeMicros();
- while (!message_queue_->Insert(&message)) {
- // We can't destroy the event log until we have stopped the thread,
- // so clear the message queue and try again. Note that if we clear
- // any STOP_FILE events, then the threads calling StopLogging would likely
- // wait indefinitely. However, there should not be any such calls as we
- // are executing the destructor.
- LOG(LS_WARNING) << "Clearing message queue to terminate thread.";
- message_queue_->Clear();
- }
- wake_from_hibernation_.Set();
- wake_periodically_.Set(); // Wake up the output thread.
- thread_.Stop(); // Wait for the thread to terminate.
-}
-
-void RtcEventLogHelperThread::WaitForFileFinished() {
- wake_from_hibernation_.Set();
- wake_periodically_.Set();
- file_finished_.Wait(rtc::Event::kForever);
-}
-
-void RtcEventLogHelperThread::SignalNewEvent() {
- wake_from_hibernation_.Set();
-}
-
-bool RtcEventLogHelperThread::AppendEventToString(rtclog::Event* event) {
- rtclog::EventStream event_stream;
- event_stream.add_stream();
- event_stream.mutable_stream(0)->Swap(event);
- // We create a new event stream per event but because of the way protobufs
- // are encoded, events can be merged by concatenating them. Therefore,
- // it will look like a single stream when we read it back from file.
- bool stop = true;
- if (written_bytes_ + static_cast<int64_t>(output_string_.size()) +
- event_stream.ByteSize() <=
- max_size_bytes_) {
- event_stream.AppendToString(&output_string_);
- stop = false;
- }
- // Swap the event back so that we don't mix event types in the queues.
- event_stream.mutable_stream(0)->Swap(event);
- return stop;
-}
-
-bool RtcEventLogHelperThread::LogToMemory() {
- RTC_DCHECK(!file_->is_open());
- bool message_received = false;
-
- // Process each event earlier than the current time and append it to the
- // appropriate history_.
- int64_t current_time = rtc::TimeMicros();
- if (!has_recent_event_) {
- has_recent_event_ = event_queue_->Remove(&most_recent_event_);
- }
- while (has_recent_event_ &&
- most_recent_event_->timestamp_us() <= current_time) {
- if (IsConfigEvent(*most_recent_event_)) {
- config_history_.push_back(std::move(most_recent_event_));
- } else {
- history_.push_back(std::move(most_recent_event_));
- if (history_.size() > kEventsInHistory)
- history_.pop_front();
- }
- has_recent_event_ = event_queue_->Remove(&most_recent_event_);
- message_received = true;
- }
- return message_received;
-}
-
-void RtcEventLogHelperThread::StartLogFile() {
- RTC_DCHECK(file_->is_open());
- bool stop = false;
- output_string_.clear();
-
- // Create and serialize the LOG_START event.
- rtclog::Event start_event;
- start_event.set_timestamp_us(start_time_);
- start_event.set_type(rtclog::Event::LOG_START);
- AppendEventToString(&start_event);
-
- // Serialize the config information for all old streams.
- for (auto& event : config_history_) {
- AppendEventToString(event.get());
- }
-
- // Serialize the events in the event queue.
- while (!history_.empty() && !stop) {
- stop = AppendEventToString(history_.front().get());
- if (!stop) {
- history_.pop_front();
- }
- }
-
- // Write to file.
- if (!file_->Write(output_string_.data(), output_string_.size())) {
- LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file.";
- // The current FileWrapper implementation closes the file on error.
- RTC_DCHECK(!file_->is_open());
- return;
- }
- written_bytes_ += output_string_.size();
-
- // Free the allocated memory since we probably won't need this amount of
- // space again.
- output_string_.clear();
- output_string_.shrink_to_fit();
-
- if (stop) {
- RTC_DCHECK(file_->is_open());
- StopLogFile();
- }
-}
-
-bool RtcEventLogHelperThread::LogToFile() {
- RTC_DCHECK(file_->is_open());
- output_string_.clear();
- bool message_received = false;
-
- // Append each event older than both the current time and the stop time
- // to the output_string_.
- int64_t current_time = rtc::TimeMicros();
- int64_t time_limit = std::min(current_time, stop_time_);
- if (!has_recent_event_) {
- has_recent_event_ = event_queue_->Remove(&most_recent_event_);
- }
- bool stop = false;
- while (!stop && has_recent_event_ &&
- most_recent_event_->timestamp_us() <= time_limit) {
- stop = AppendEventToString(most_recent_event_.get());
- if (!stop) {
- if (IsConfigEvent(*most_recent_event_)) {
- config_history_.push_back(std::move(most_recent_event_));
- }
- has_recent_event_ = event_queue_->Remove(&most_recent_event_);
- }
- message_received = true;
- }
-
- // Write string to file.
- if (!file_->Write(output_string_.data(), output_string_.size())) {
- LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file.";
- // The current FileWrapper implementation closes the file on error.
- RTC_DCHECK(!file_->is_open());
- return message_received;
- }
- written_bytes_ += output_string_.size();
-
- // We want to stop logging if we have reached the file size limit. We also
- // want to stop logging if the remaining events are more recent than the
- // time limit, or in other words if we have terminated the loop despite
- // having more events in the queue.
- if ((has_recent_event_ && most_recent_event_->timestamp_us() > stop_time_) ||
- stop) {
- RTC_DCHECK(file_->is_open());
- StopLogFile();
- }
- return message_received;
-}
-
-void RtcEventLogHelperThread::StopLogFile() {
- RTC_DCHECK(file_->is_open());
- output_string_.clear();
-
- rtclog::Event end_event;
- // This function can be called either because we have reached the stop time,
- // or because we have reached the log file size limit. Therefore, use the
- // current time if we have not reached the time limit.
- end_event.set_timestamp_us(
- std::min(stop_time_, rtc::TimeMicros()));
- end_event.set_type(rtclog::Event::LOG_END);
- AppendEventToString(&end_event);
-
- if (written_bytes_ + static_cast<int64_t>(output_string_.size()) <=
- max_size_bytes_) {
- if (!file_->Write(output_string_.data(), output_string_.size())) {
- LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file.";
- // The current FileWrapper implementation closes the file on error.
- RTC_DCHECK(!file_->is_open());
- }
- written_bytes_ += output_string_.size();
- }
-
- max_size_bytes_ = std::numeric_limits<int64_t>::max();
- written_bytes_ = 0;
- start_time_ = 0;
- stop_time_ = std::numeric_limits<int64_t>::max();
- output_string_.clear();
- file_->CloseFile();
- RTC_DCHECK(!file_->is_open());
-}
-
-void RtcEventLogHelperThread::ProcessEvents() {
- ControlMessage message;
-
- while (true) {
- bool message_received = false;
- // Process control messages.
- while (message_queue_->Remove(&message)) {
- switch (message.message_type) {
- case ControlMessage::START_FILE:
- if (!file_->is_open()) {
- max_size_bytes_ = message.max_size_bytes;
- start_time_ = message.start_time;
- stop_time_ = message.stop_time;
- file_.swap(message.file);
- StartLogFile();
- } else {
- // Already started. Ignore message and close file handle.
- message.file->CloseFile();
- }
- message_received = true;
- break;
- case ControlMessage::STOP_FILE:
- if (file_->is_open()) {
- stop_time_ = message.stop_time;
- LogToFile(); // Log remaining events from message queues.
- }
- // LogToFile might stop on it's own so we need to recheck the state.
- if (file_->is_open()) {
- StopLogFile();
- }
- file_finished_.Set();
- message_received = true;
- break;
- case ControlMessage::TERMINATE_THREAD:
- if (file_->is_open()) {
- StopLogFile();
- }
- return;
- }
- }
-
- // Write events to file or memory.
- if (file_->is_open()) {
- message_received |= LogToFile();
- } else {
- message_received |= LogToMemory();
- }
-
- // Accumulate a new batch of events instead of processing them one at a
- // time.
- if (message_received) {
- wake_periodically_.Wait(100);
- } else {
- wake_from_hibernation_.Wait(rtc::Event::kForever);
- }
- }
-}
-
-void RtcEventLogHelperThread::ThreadOutputFunction(void* obj) {
- RtcEventLogHelperThread* helper = static_cast<RtcEventLogHelperThread*>(obj);
- helper->ProcessEvents();
-}
-
-} // namespace webrtc
-
-#endif // ENABLE_RTC_EVENT_LOG
« no previous file with comments | « webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.h ('k') | webrtc/pc/peerconnection.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698