OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.h" | 11 #include "webrtc/logging/rtc_event_log/rtc_event_log_helper_thread.h" |
12 | 12 |
13 #include <algorithm> | 13 #include <algorithm> |
14 | 14 |
15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/base/timeutils.h" |
16 #include "webrtc/system_wrappers/include/logging.h" | 17 #include "webrtc/system_wrappers/include/logging.h" |
17 | 18 |
18 #ifdef ENABLE_RTC_EVENT_LOG | 19 #ifdef ENABLE_RTC_EVENT_LOG |
19 | 20 |
20 namespace webrtc { | 21 namespace webrtc { |
21 | 22 |
22 namespace { | 23 namespace { |
23 const int kEventsInHistory = 10000; | 24 const int kEventsInHistory = 10000; |
24 | 25 |
25 bool IsConfigEvent(const rtclog::Event& event) { | 26 bool IsConfigEvent(const rtclog::Event& event) { |
26 rtclog::Event_EventType event_type = event.type(); | 27 rtclog::Event_EventType event_type = event.type(); |
27 return event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT || | 28 return event_type == rtclog::Event::VIDEO_RECEIVER_CONFIG_EVENT || |
28 event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT || | 29 event_type == rtclog::Event::VIDEO_SENDER_CONFIG_EVENT || |
29 event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT || | 30 event_type == rtclog::Event::AUDIO_RECEIVER_CONFIG_EVENT || |
30 event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT; | 31 event_type == rtclog::Event::AUDIO_SENDER_CONFIG_EVENT; |
31 } | 32 } |
32 } // namespace | 33 } // namespace |
33 | 34 |
34 // RtcEventLogImpl member functions. | 35 // RtcEventLogImpl member functions. |
35 RtcEventLogHelperThread::RtcEventLogHelperThread( | 36 RtcEventLogHelperThread::RtcEventLogHelperThread( |
36 SwapQueue<ControlMessage>* message_queue, | 37 SwapQueue<ControlMessage>* message_queue, |
37 SwapQueue<std::unique_ptr<rtclog::Event>>* event_queue, | 38 SwapQueue<std::unique_ptr<rtclog::Event>>* event_queue) |
38 const Clock* const clock) | |
39 : message_queue_(message_queue), | 39 : message_queue_(message_queue), |
40 event_queue_(event_queue), | 40 event_queue_(event_queue), |
41 history_(kEventsInHistory), | 41 history_(kEventsInHistory), |
42 config_history_(), | 42 config_history_(), |
43 file_(FileWrapper::Create()), | 43 file_(FileWrapper::Create()), |
44 thread_(&ThreadOutputFunction, this, "RtcEventLog thread"), | 44 thread_(&ThreadOutputFunction, this, "RtcEventLog thread"), |
45 max_size_bytes_(std::numeric_limits<int64_t>::max()), | 45 max_size_bytes_(std::numeric_limits<int64_t>::max()), |
46 written_bytes_(0), | 46 written_bytes_(0), |
47 start_time_(0), | 47 start_time_(0), |
48 stop_time_(std::numeric_limits<int64_t>::max()), | 48 stop_time_(std::numeric_limits<int64_t>::max()), |
49 has_recent_event_(false), | 49 has_recent_event_(false), |
50 most_recent_event_(), | 50 most_recent_event_(), |
51 output_string_(), | 51 output_string_(), |
52 wake_periodically_(false, false), | 52 wake_periodically_(false, false), |
53 wake_from_hibernation_(false, false), | 53 wake_from_hibernation_(false, false), |
54 file_finished_(false, false), | 54 file_finished_(false, false) { |
55 clock_(clock) { | |
56 RTC_DCHECK(message_queue_); | 55 RTC_DCHECK(message_queue_); |
57 RTC_DCHECK(event_queue_); | 56 RTC_DCHECK(event_queue_); |
58 RTC_DCHECK(clock_); | |
59 thread_.Start(); | 57 thread_.Start(); |
60 } | 58 } |
61 | 59 |
62 RtcEventLogHelperThread::~RtcEventLogHelperThread() { | 60 RtcEventLogHelperThread::~RtcEventLogHelperThread() { |
63 ControlMessage message; | 61 ControlMessage message; |
64 message.message_type = ControlMessage::TERMINATE_THREAD; | 62 message.message_type = ControlMessage::TERMINATE_THREAD; |
65 message.stop_time = clock_->TimeInMicroseconds(); | 63 message.stop_time = rtc::TimeMicros(); |
66 while (!message_queue_->Insert(&message)) { | 64 while (!message_queue_->Insert(&message)) { |
67 // We can't destroy the event log until we have stopped the thread, | 65 // We can't destroy the event log until we have stopped the thread, |
68 // so clear the message queue and try again. Note that if we clear | 66 // so clear the message queue and try again. Note that if we clear |
69 // any STOP_FILE events, then the threads calling StopLogging would likely | 67 // any STOP_FILE events, then the threads calling StopLogging would likely |
70 // wait indefinitely. However, there should not be any such calls as we | 68 // wait indefinitely. However, there should not be any such calls as we |
71 // are executing the destructor. | 69 // are executing the destructor. |
72 LOG(LS_WARNING) << "Clearing message queue to terminate thread."; | 70 LOG(LS_WARNING) << "Clearing message queue to terminate thread."; |
73 message_queue_->Clear(); | 71 message_queue_->Clear(); |
74 } | 72 } |
75 wake_from_hibernation_.Set(); | 73 wake_from_hibernation_.Set(); |
(...skipping 29 matching lines...) Expand all Loading... |
105 event_stream.mutable_stream(0)->Swap(event); | 103 event_stream.mutable_stream(0)->Swap(event); |
106 return stop; | 104 return stop; |
107 } | 105 } |
108 | 106 |
109 bool RtcEventLogHelperThread::LogToMemory() { | 107 bool RtcEventLogHelperThread::LogToMemory() { |
110 RTC_DCHECK(!file_->is_open()); | 108 RTC_DCHECK(!file_->is_open()); |
111 bool message_received = false; | 109 bool message_received = false; |
112 | 110 |
113 // Process each event earlier than the current time and append it to the | 111 // Process each event earlier than the current time and append it to the |
114 // appropriate history_. | 112 // appropriate history_. |
115 int64_t current_time = clock_->TimeInMicroseconds(); | 113 int64_t current_time = rtc::TimeMicros(); |
116 if (!has_recent_event_) { | 114 if (!has_recent_event_) { |
117 has_recent_event_ = event_queue_->Remove(&most_recent_event_); | 115 has_recent_event_ = event_queue_->Remove(&most_recent_event_); |
118 } | 116 } |
119 while (has_recent_event_ && | 117 while (has_recent_event_ && |
120 most_recent_event_->timestamp_us() <= current_time) { | 118 most_recent_event_->timestamp_us() <= current_time) { |
121 if (IsConfigEvent(*most_recent_event_)) { | 119 if (IsConfigEvent(*most_recent_event_)) { |
122 config_history_.push_back(std::move(most_recent_event_)); | 120 config_history_.push_back(std::move(most_recent_event_)); |
123 } else { | 121 } else { |
124 history_.push_back(std::move(most_recent_event_)); | 122 history_.push_back(std::move(most_recent_event_)); |
125 } | 123 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 171 } |
174 } | 172 } |
175 | 173 |
176 bool RtcEventLogHelperThread::LogToFile() { | 174 bool RtcEventLogHelperThread::LogToFile() { |
177 RTC_DCHECK(file_->is_open()); | 175 RTC_DCHECK(file_->is_open()); |
178 output_string_.clear(); | 176 output_string_.clear(); |
179 bool message_received = false; | 177 bool message_received = false; |
180 | 178 |
181 // Append each event older than both the current time and the stop time | 179 // Append each event older than both the current time and the stop time |
182 // to the output_string_. | 180 // to the output_string_. |
183 int64_t current_time = clock_->TimeInMicroseconds(); | 181 int64_t current_time = rtc::TimeMicros(); |
184 int64_t time_limit = std::min(current_time, stop_time_); | 182 int64_t time_limit = std::min(current_time, stop_time_); |
185 if (!has_recent_event_) { | 183 if (!has_recent_event_) { |
186 has_recent_event_ = event_queue_->Remove(&most_recent_event_); | 184 has_recent_event_ = event_queue_->Remove(&most_recent_event_); |
187 } | 185 } |
188 bool stop = false; | 186 bool stop = false; |
189 while (!stop && has_recent_event_ && | 187 while (!stop && has_recent_event_ && |
190 most_recent_event_->timestamp_us() <= time_limit) { | 188 most_recent_event_->timestamp_us() <= time_limit) { |
191 stop = AppendEventToString(most_recent_event_.get()); | 189 stop = AppendEventToString(most_recent_event_.get()); |
192 if (!stop) { | 190 if (!stop) { |
193 if (IsConfigEvent(*most_recent_event_)) { | 191 if (IsConfigEvent(*most_recent_event_)) { |
(...skipping 27 matching lines...) Expand all Loading... |
221 | 219 |
222 void RtcEventLogHelperThread::StopLogFile() { | 220 void RtcEventLogHelperThread::StopLogFile() { |
223 RTC_DCHECK(file_->is_open()); | 221 RTC_DCHECK(file_->is_open()); |
224 output_string_.clear(); | 222 output_string_.clear(); |
225 | 223 |
226 rtclog::Event end_event; | 224 rtclog::Event end_event; |
227 // This function can be called either because we have reached the stop time, | 225 // This function can be called either because we have reached the stop time, |
228 // or because we have reached the log file size limit. Therefore, use the | 226 // or because we have reached the log file size limit. Therefore, use the |
229 // current time if we have not reached the time limit. | 227 // current time if we have not reached the time limit. |
230 end_event.set_timestamp_us( | 228 end_event.set_timestamp_us( |
231 std::min(stop_time_, clock_->TimeInMicroseconds())); | 229 std::min(stop_time_, rtc::TimeMicros())); |
232 end_event.set_type(rtclog::Event::LOG_END); | 230 end_event.set_type(rtclog::Event::LOG_END); |
233 AppendEventToString(&end_event); | 231 AppendEventToString(&end_event); |
234 | 232 |
235 if (written_bytes_ + static_cast<int64_t>(output_string_.size()) <= | 233 if (written_bytes_ + static_cast<int64_t>(output_string_.size()) <= |
236 max_size_bytes_) { | 234 max_size_bytes_) { |
237 if (!file_->Write(output_string_.data(), output_string_.size())) { | 235 if (!file_->Write(output_string_.data(), output_string_.size())) { |
238 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; | 236 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; |
239 // The current FileWrapper implementation closes the file on error. | 237 // The current FileWrapper implementation closes the file on error. |
240 RTC_DCHECK(!file_->is_open()); | 238 RTC_DCHECK(!file_->is_open()); |
241 } | 239 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 | 309 |
312 bool RtcEventLogHelperThread::ThreadOutputFunction(void* obj) { | 310 bool RtcEventLogHelperThread::ThreadOutputFunction(void* obj) { |
313 RtcEventLogHelperThread* helper = static_cast<RtcEventLogHelperThread*>(obj); | 311 RtcEventLogHelperThread* helper = static_cast<RtcEventLogHelperThread*>(obj); |
314 helper->ProcessEvents(); | 312 helper->ProcessEvents(); |
315 return false; | 313 return false; |
316 } | 314 } |
317 | 315 |
318 } // namespace webrtc | 316 } // namespace webrtc |
319 | 317 |
320 #endif // ENABLE_RTC_EVENT_LOG | 318 #endif // ENABLE_RTC_EVENT_LOG |
OLD | NEW |