| 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 |