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 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 max_size_bytes_) { | 100 max_size_bytes_) { |
101 event_stream.AppendToString(&output_string_); | 101 event_stream.AppendToString(&output_string_); |
102 stop = false; | 102 stop = false; |
103 } | 103 } |
104 // Swap the event back so that we don't mix event types in the queues. | 104 // Swap the event back so that we don't mix event types in the queues. |
105 event_stream.mutable_stream(0)->Swap(event); | 105 event_stream.mutable_stream(0)->Swap(event); |
106 return stop; | 106 return stop; |
107 } | 107 } |
108 | 108 |
109 bool RtcEventLogHelperThread::LogToMemory() { | 109 bool RtcEventLogHelperThread::LogToMemory() { |
110 RTC_DCHECK(!file_->Open()); | 110 RTC_DCHECK(!file_->is_open()); |
111 bool message_received = false; | 111 bool message_received = false; |
112 | 112 |
113 // Process each event earlier than the current time and append it to the | 113 // Process each event earlier than the current time and append it to the |
114 // appropriate history_. | 114 // appropriate history_. |
115 int64_t current_time = clock_->TimeInMicroseconds(); | 115 int64_t current_time = clock_->TimeInMicroseconds(); |
116 if (!has_recent_event_) { | 116 if (!has_recent_event_) { |
117 has_recent_event_ = event_queue_->Remove(&most_recent_event_); | 117 has_recent_event_ = event_queue_->Remove(&most_recent_event_); |
118 } | 118 } |
119 while (has_recent_event_ && | 119 while (has_recent_event_ && |
120 most_recent_event_->timestamp_us() <= current_time) { | 120 most_recent_event_->timestamp_us() <= current_time) { |
121 if (IsConfigEvent(*most_recent_event_)) { | 121 if (IsConfigEvent(*most_recent_event_)) { |
122 config_history_.push_back(std::move(most_recent_event_)); | 122 config_history_.push_back(std::move(most_recent_event_)); |
123 } else { | 123 } else { |
124 history_.push_back(std::move(most_recent_event_)); | 124 history_.push_back(std::move(most_recent_event_)); |
125 } | 125 } |
126 has_recent_event_ = event_queue_->Remove(&most_recent_event_); | 126 has_recent_event_ = event_queue_->Remove(&most_recent_event_); |
127 message_received = true; | 127 message_received = true; |
128 } | 128 } |
129 return message_received; | 129 return message_received; |
130 } | 130 } |
131 | 131 |
132 void RtcEventLogHelperThread::StartLogFile() { | 132 void RtcEventLogHelperThread::StartLogFile() { |
133 RTC_DCHECK(file_->Open()); | 133 RTC_DCHECK(file_->is_open()); |
134 bool stop = false; | 134 bool stop = false; |
135 output_string_.clear(); | 135 output_string_.clear(); |
136 | 136 |
137 // Create and serialize the LOG_START event. | 137 // Create and serialize the LOG_START event. |
138 rtclog::Event start_event; | 138 rtclog::Event start_event; |
139 start_event.set_timestamp_us(start_time_); | 139 start_event.set_timestamp_us(start_time_); |
140 start_event.set_type(rtclog::Event::LOG_START); | 140 start_event.set_type(rtclog::Event::LOG_START); |
141 AppendEventToString(&start_event); | 141 AppendEventToString(&start_event); |
142 | 142 |
143 // Serialize the config information for all old streams. | 143 // Serialize the config information for all old streams. |
144 for (auto& event : config_history_) { | 144 for (auto& event : config_history_) { |
145 AppendEventToString(event.get()); | 145 AppendEventToString(event.get()); |
146 } | 146 } |
147 | 147 |
148 // Serialize the events in the event queue. | 148 // Serialize the events in the event queue. |
149 while (!history_.empty() && !stop) { | 149 while (!history_.empty() && !stop) { |
150 stop = AppendEventToString(history_.front().get()); | 150 stop = AppendEventToString(history_.front().get()); |
151 if (!stop) { | 151 if (!stop) { |
152 history_.pop_front(); | 152 history_.pop_front(); |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 // Write to file. | 156 // Write to file. |
157 if (!file_->Write(output_string_.data(), output_string_.size())) { | 157 if (!file_->Write(output_string_.data(), output_string_.size())) { |
158 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; | 158 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; |
159 // The current FileWrapper implementation closes the file on error. | 159 // The current FileWrapper implementation closes the file on error. |
160 RTC_DCHECK(!file_->Open()); | 160 RTC_DCHECK(!file_->is_open()); |
161 return; | 161 return; |
162 } | 162 } |
163 written_bytes_ += output_string_.size(); | 163 written_bytes_ += output_string_.size(); |
164 | 164 |
165 // Free the allocated memory since we probably won't need this amount of | 165 // Free the allocated memory since we probably won't need this amount of |
166 // space again. | 166 // space again. |
167 output_string_.clear(); | 167 output_string_.clear(); |
168 output_string_.shrink_to_fit(); | 168 output_string_.shrink_to_fit(); |
169 | 169 |
170 if (stop) { | 170 if (stop) { |
171 RTC_DCHECK(file_->Open()); | 171 RTC_DCHECK(file_->is_open()); |
172 StopLogFile(); | 172 StopLogFile(); |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 bool RtcEventLogHelperThread::LogToFile() { | 176 bool RtcEventLogHelperThread::LogToFile() { |
177 RTC_DCHECK(file_->Open()); | 177 RTC_DCHECK(file_->is_open()); |
178 output_string_.clear(); | 178 output_string_.clear(); |
179 bool message_received = false; | 179 bool message_received = false; |
180 | 180 |
181 // Append each event older than both the current time and the stop time | 181 // Append each event older than both the current time and the stop time |
182 // to the output_string_. | 182 // to the output_string_. |
183 int64_t current_time = clock_->TimeInMicroseconds(); | 183 int64_t current_time = clock_->TimeInMicroseconds(); |
184 int64_t time_limit = std::min(current_time, stop_time_); | 184 int64_t time_limit = std::min(current_time, stop_time_); |
185 if (!has_recent_event_) { | 185 if (!has_recent_event_) { |
186 has_recent_event_ = event_queue_->Remove(&most_recent_event_); | 186 has_recent_event_ = event_queue_->Remove(&most_recent_event_); |
187 } | 187 } |
188 bool stop = false; | 188 bool stop = false; |
189 while (!stop && has_recent_event_ && | 189 while (!stop && has_recent_event_ && |
190 most_recent_event_->timestamp_us() <= time_limit) { | 190 most_recent_event_->timestamp_us() <= time_limit) { |
191 stop = AppendEventToString(most_recent_event_.get()); | 191 stop = AppendEventToString(most_recent_event_.get()); |
192 if (!stop) { | 192 if (!stop) { |
193 if (IsConfigEvent(*most_recent_event_)) { | 193 if (IsConfigEvent(*most_recent_event_)) { |
194 config_history_.push_back(std::move(most_recent_event_)); | 194 config_history_.push_back(std::move(most_recent_event_)); |
195 } | 195 } |
196 has_recent_event_ = event_queue_->Remove(&most_recent_event_); | 196 has_recent_event_ = event_queue_->Remove(&most_recent_event_); |
197 } | 197 } |
198 message_received = true; | 198 message_received = true; |
199 } | 199 } |
200 | 200 |
201 // Write string to file. | 201 // Write string to file. |
202 if (!file_->Write(output_string_.data(), output_string_.size())) { | 202 if (!file_->Write(output_string_.data(), output_string_.size())) { |
203 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; | 203 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; |
204 // The current FileWrapper implementation closes the file on error. | 204 // The current FileWrapper implementation closes the file on error. |
205 RTC_DCHECK(!file_->Open()); | 205 RTC_DCHECK(!file_->is_open()); |
206 return message_received; | 206 return message_received; |
207 } | 207 } |
208 written_bytes_ += output_string_.size(); | 208 written_bytes_ += output_string_.size(); |
209 | 209 |
210 // We want to stop logging if we have reached the file size limit. We also | 210 // We want to stop logging if we have reached the file size limit. We also |
211 // want to stop logging if the remaining events are more recent than the | 211 // want to stop logging if the remaining events are more recent than the |
212 // time limit, or in other words if we have terminated the loop despite | 212 // time limit, or in other words if we have terminated the loop despite |
213 // having more events in the queue. | 213 // having more events in the queue. |
214 if ((has_recent_event_ && most_recent_event_->timestamp_us() > stop_time_) || | 214 if ((has_recent_event_ && most_recent_event_->timestamp_us() > stop_time_) || |
215 stop) { | 215 stop) { |
216 RTC_DCHECK(file_->Open()); | 216 RTC_DCHECK(file_->is_open()); |
217 StopLogFile(); | 217 StopLogFile(); |
218 } | 218 } |
219 return message_received; | 219 return message_received; |
220 } | 220 } |
221 | 221 |
222 void RtcEventLogHelperThread::StopLogFile() { | 222 void RtcEventLogHelperThread::StopLogFile() { |
223 RTC_DCHECK(file_->Open()); | 223 RTC_DCHECK(file_->is_open()); |
224 output_string_.clear(); | 224 output_string_.clear(); |
225 | 225 |
226 rtclog::Event end_event; | 226 rtclog::Event end_event; |
227 end_event.set_timestamp_us(stop_time_); | 227 end_event.set_timestamp_us(stop_time_); |
228 end_event.set_type(rtclog::Event::LOG_END); | 228 end_event.set_type(rtclog::Event::LOG_END); |
229 AppendEventToString(&end_event); | 229 AppendEventToString(&end_event); |
230 | 230 |
231 if (written_bytes_ + static_cast<int64_t>(output_string_.size()) <= | 231 if (written_bytes_ + static_cast<int64_t>(output_string_.size()) <= |
232 max_size_bytes_) { | 232 max_size_bytes_) { |
233 if (!file_->Write(output_string_.data(), output_string_.size())) { | 233 if (!file_->Write(output_string_.data(), output_string_.size())) { |
234 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; | 234 LOG(LS_ERROR) << "FileWrapper failed to write WebRtcEventLog file."; |
235 // The current FileWrapper implementation closes the file on error. | 235 // The current FileWrapper implementation closes the file on error. |
236 RTC_DCHECK(!file_->Open()); | 236 RTC_DCHECK(!file_->is_open()); |
237 } | 237 } |
238 written_bytes_ += output_string_.size(); | 238 written_bytes_ += output_string_.size(); |
239 } | 239 } |
240 | 240 |
241 max_size_bytes_ = std::numeric_limits<int64_t>::max(); | 241 max_size_bytes_ = std::numeric_limits<int64_t>::max(); |
242 written_bytes_ = 0; | 242 written_bytes_ = 0; |
243 start_time_ = 0; | 243 start_time_ = 0; |
244 stop_time_ = std::numeric_limits<int64_t>::max(); | 244 stop_time_ = std::numeric_limits<int64_t>::max(); |
245 output_string_.clear(); | 245 output_string_.clear(); |
246 file_->CloseFile(); | 246 file_->CloseFile(); |
247 RTC_DCHECK(!file_->Open()); | 247 RTC_DCHECK(!file_->is_open()); |
248 } | 248 } |
249 | 249 |
250 void RtcEventLogHelperThread::ProcessEvents() { | 250 void RtcEventLogHelperThread::ProcessEvents() { |
251 ControlMessage message; | 251 ControlMessage message; |
252 | 252 |
253 while (true) { | 253 while (true) { |
254 bool message_received = false; | 254 bool message_received = false; |
255 // Process control messages. | 255 // Process control messages. |
256 while (message_queue_->Remove(&message)) { | 256 while (message_queue_->Remove(&message)) { |
257 switch (message.message_type) { | 257 switch (message.message_type) { |
258 case ControlMessage::START_FILE: | 258 case ControlMessage::START_FILE: |
259 if (!file_->Open()) { | 259 if (!file_->is_open()) { |
260 max_size_bytes_ = message.max_size_bytes; | 260 max_size_bytes_ = message.max_size_bytes; |
261 start_time_ = message.start_time; | 261 start_time_ = message.start_time; |
262 stop_time_ = message.stop_time; | 262 stop_time_ = message.stop_time; |
263 file_.swap(message.file); | 263 file_.swap(message.file); |
264 StartLogFile(); | 264 StartLogFile(); |
265 } else { | 265 } else { |
266 // Already started. Ignore message and close file handle. | 266 // Already started. Ignore message and close file handle. |
267 message.file->CloseFile(); | 267 message.file->CloseFile(); |
268 } | 268 } |
269 message_received = true; | 269 message_received = true; |
270 break; | 270 break; |
271 case ControlMessage::STOP_FILE: | 271 case ControlMessage::STOP_FILE: |
272 if (file_->Open()) { | 272 if (file_->is_open()) { |
273 stop_time_ = message.stop_time; | 273 stop_time_ = message.stop_time; |
274 LogToFile(); // Log remaining events from message queues. | 274 LogToFile(); // Log remaining events from message queues. |
275 } | 275 } |
276 // LogToFile might stop on it's own so we need to recheck the state. | 276 // LogToFile might stop on it's own so we need to recheck the state. |
277 if (file_->Open()) { | 277 if (file_->is_open()) { |
278 StopLogFile(); | 278 StopLogFile(); |
279 } | 279 } |
280 file_finished_.Set(); | 280 file_finished_.Set(); |
281 message_received = true; | 281 message_received = true; |
282 break; | 282 break; |
283 case ControlMessage::TERMINATE_THREAD: | 283 case ControlMessage::TERMINATE_THREAD: |
284 if (file_->Open()) { | 284 if (file_->is_open()) { |
285 StopLogFile(); | 285 StopLogFile(); |
286 } | 286 } |
287 return; | 287 return; |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 // Write events to file or memory. | 291 // Write events to file or memory. |
292 if (file_->Open()) { | 292 if (file_->is_open()) { |
293 message_received |= LogToFile(); | 293 message_received |= LogToFile(); |
294 } else { | 294 } else { |
295 message_received |= LogToMemory(); | 295 message_received |= LogToMemory(); |
296 } | 296 } |
297 | 297 |
298 // Accumulate a new batch of events instead of processing them one at a | 298 // Accumulate a new batch of events instead of processing them one at a |
299 // time. | 299 // time. |
300 if (message_received) { | 300 if (message_received) { |
301 wake_periodically_.Wait(100); | 301 wake_periodically_.Wait(100); |
302 } else { | 302 } else { |
303 wake_from_hibernation_.Wait(rtc::Event::kForever); | 303 wake_from_hibernation_.Wait(rtc::Event::kForever); |
304 } | 304 } |
305 } | 305 } |
306 } | 306 } |
307 | 307 |
308 bool RtcEventLogHelperThread::ThreadOutputFunction(void* obj) { | 308 bool RtcEventLogHelperThread::ThreadOutputFunction(void* obj) { |
309 RtcEventLogHelperThread* helper = static_cast<RtcEventLogHelperThread*>(obj); | 309 RtcEventLogHelperThread* helper = static_cast<RtcEventLogHelperThread*>(obj); |
310 helper->ProcessEvents(); | 310 helper->ProcessEvents(); |
311 return false; | 311 return false; |
312 } | 312 } |
313 | 313 |
314 } // namespace webrtc | 314 } // namespace webrtc |
315 | 315 |
316 #endif // ENABLE_RTC_EVENT_LOG | 316 #endif // ENABLE_RTC_EVENT_LOG |
OLD | NEW |