Chromium Code Reviews| Index: content/browser/tracing/tracing_controller_impl.cc |
| diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc |
| index 70edf234be4be8849a0883912a32216293d48130..88b076d137bbcb3d246f4f5454ed6b1e6e806ae1 100644 |
| --- a/content/browser/tracing/tracing_controller_impl.cc |
| +++ b/content/browser/tracing/tracing_controller_impl.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/macros.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/sys_info.h" |
| +#include "base/thread_task_runner_handle.h" |
| #include "base/trace_event/trace_event.h" |
| #include "build/build_config.h" |
| #include "content/browser/tracing/file_tracing_provider_impl.h" |
| @@ -50,6 +51,7 @@ const char kChromeTracingAgentName[] = "chrome"; |
| const char kETWTracingAgentName[] = "etw"; |
| const char kChromeTraceLabel[] = "traceEvents"; |
| +const int kStartTracingTimeout = 30; |
| const int kIssueClockSyncTimeout = 30; |
| std::string GetNetworkTypeString() { |
| @@ -144,7 +146,8 @@ TracingController* TracingController::GetInstance() { |
| } |
| TracingControllerImpl::TracingControllerImpl() |
| - : pending_stop_tracing_ack_count_(0), |
| + : pending_start_tracing_ack_count_(0), |
| + pending_stop_tracing_ack_count_(0), |
| pending_capture_monitoring_snapshot_ack_count_(0), |
| pending_trace_log_status_ack_count_(0), |
| maximum_trace_buffer_usage_(0), |
| @@ -218,6 +221,10 @@ bool TracingControllerImpl::StartTracing( |
| return false; |
| is_tracing_ = true; |
| start_tracing_done_callback_ = callback; |
| + start_tracing_trace_config_.reset( |
| + new base::trace_event::TraceConfig(trace_config)); |
| + // We at least have to wait for the Chrome tracing agent to start. |
| + pending_start_tracing_ack_count_ = 1; |
|
Zhen Wang
2016/01/25 20:35:32
nit: Maybe it is better to move the count for Chro
charliea (OOO until 10-5)
2016/01/25 21:15:24
Done.
|
| #if defined(OS_ANDROID) |
| if (pending_get_categories_done_callback_.is_null()) |
| @@ -225,51 +232,70 @@ bool TracingControllerImpl::StartTracing( |
| #endif |
| if (trace_config.IsSystraceEnabled()) { |
| - if (PowerTracingAgent::GetInstance()->StartAgentTracing(trace_config)) |
| - additional_tracing_agents_.push_back(PowerTracingAgent::GetInstance()); |
| + PowerTracingAgent::GetInstance()->StartAgentTracing( |
| + trace_config, |
| + base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, |
| + base::Unretained(this))); |
| + ++pending_start_tracing_ack_count_; |
| + |
| #if defined(OS_CHROMEOS) |
| chromeos::DebugDaemonClient* debug_daemon = |
| chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); |
| - if (debug_daemon && debug_daemon->StartAgentTracing(trace_config)) { |
| - debug_daemon->SetStopAgentTracingTaskRunner( |
| - BrowserThread::GetBlockingPool()); |
| - additional_tracing_agents_.push_back( |
| - chromeos::DBusThreadManager::Get()->GetDebugDaemonClient()); |
| + if (debug_daemon) { |
| + debug_daemon->StartAgentTracing( |
| + trace_config, |
| + base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, |
| + base::Unretained(this))); |
| + ++pending_start_tracing_ack_count_; |
| } |
| #elif defined(OS_WIN) |
| - if (EtwSystemEventConsumer::GetInstance()->StartAgentTracing( |
| - trace_config)) { |
| - additional_tracing_agents_.push_back( |
| - EtwSystemEventConsumer::GetInstance()); |
| - } |
| + EtwSystemEventConsumer::GetInstance()->StartAgentTracing( |
| + trace_config, |
| + base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, |
| + base::Unretained(this))); |
| + ++pending_start_tracing_ack_count_; |
| #endif |
| } |
| // TraceLog may have been enabled in startup tracing before threads are ready. |
| if (TraceLog::GetInstance()->IsEnabled()) |
| return true; |
| - return StartAgentTracing(trace_config); |
| + |
| + StartAgentTracing(trace_config, |
| + base::Bind(&TracingControllerImpl::OnStartAgentTracingAcked, |
| + base::Unretained(this))); |
| + |
| + // Set a deadline to ensure all agents ack within a reasonable time frame. |
| + if (!start_tracing_done_callback_.is_null()) { |
|
Zhen Wang
2016/01/25 20:35:32
I think we always want to have the timer.
start_t
charliea (OOO until 10-5)
2016/01/25 21:15:24
Thanks for catching that! This is left-over from w
|
| + start_tracing_timer_.Start( |
| + FROM_HERE, base::TimeDelta::FromSeconds(kStartTracingTimeout), |
| + base::Bind(&TracingControllerImpl::OnAllTracingAgentsStarted, |
| + base::Unretained(this))); |
| + } |
| + |
| + return true; |
| } |
| -void TracingControllerImpl::OnStartAgentTracingDone( |
| - const TraceConfig& trace_config) { |
| +void TracingControllerImpl::OnAllTracingAgentsStarted() { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| TRACE_EVENT_API_ADD_METADATA_EVENT("IsTimeTicksHighResolution", "value", |
| base::TimeTicks::IsHighResolution()); |
| - TRACE_EVENT_API_ADD_METADATA_EVENT("TraceConfig", "value", |
| - trace_config.AsConvertableToTraceFormat()); |
| + TRACE_EVENT_API_ADD_METADATA_EVENT( |
| + "TraceConfig", "value", |
| + start_tracing_trace_config_->AsConvertableToTraceFormat()); |
| // Notify all child processes. |
| for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin(); |
| it != trace_message_filters_.end(); ++it) { |
| - it->get()->SendBeginTracing(trace_config); |
| + it->get()->SendBeginTracing(*start_tracing_trace_config_); |
| } |
| - if (!start_tracing_done_callback_.is_null()) { |
| + if (!start_tracing_done_callback_.is_null()) |
| start_tracing_done_callback_.Run(); |
| - start_tracing_done_callback_.Reset(); |
| - } |
| + |
| + start_tracing_done_callback_.Reset(); |
| + start_tracing_trace_config_.reset(); |
| } |
| bool TracingControllerImpl::StopTracing( |
| @@ -636,6 +662,49 @@ void TracingControllerImpl::RemoveTraceMessageFilter( |
| trace_message_filters_.erase(trace_message_filter); |
| } |
| +void TracingControllerImpl::AddTracingAgent(const std::string& agent_name) { |
| +#if defined(OS_CHROMEOS) |
| + auto debug_daemon = |
| + chromeos::DBusThreadManager::Get()->GetDebugDaemonClient(); |
| + if (agent_name == debug_daemon->GetTracingAgentName()) { |
| + additional_tracing_agents_.push_back(debug_daemon); |
| + debug_daemon->SetStopAgentTracingTaskRunner( |
| + BrowserThread::GetBlockingPool()); |
| + return; |
| + } |
| +#elif defined(OS_WIN) |
| + auto etw_agent = EtwSystemEventConsumer::GetInstance(); |
| + if (agent_name == etw_agent->GetTracingAgentName()) { |
| + additional_tracing_agents_.push_back(etw_agent); |
| + return; |
| + } |
| +#endif |
| + |
| + auto power_agent = PowerTracingAgent::GetInstance(); |
| + if (agent_name == power_agent->GetTracingAgentName()) { |
| + additional_tracing_agents_.push_back(power_agent); |
| + return; |
| + } |
| + |
| + DCHECK(agent_name == kChromeTracingAgentName); |
| +} |
| + |
| +void TracingControllerImpl::OnStartAgentTracingAcked( |
| + const std::string& agent_name, |
| + bool success) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| + |
| + // Don't taken any further action if the ack came after the deadline. |
| + if (!start_tracing_timer_.IsRunning()) |
| + return; |
| + |
| + if (success) |
| + AddTracingAgent(agent_name); |
| + |
| + if (--pending_start_tracing_ack_count_ == 0) |
| + OnAllTracingAgentsStarted(); |
|
Zhen Wang
2016/01/25 20:35:32
Should also stop start_tracing_timer_ here.
charliea (OOO until 10-5)
2016/01/25 21:15:24
Doh. Done.
|
| +} |
| + |
| void TracingControllerImpl::OnStopTracingAcked( |
| TraceMessageFilter* trace_message_filter, |
| const std::vector<std::string>& known_category_groups) { |
| @@ -876,28 +945,25 @@ std::string TracingControllerImpl::GetTraceEventLabel() { |
| return kChromeTraceLabel; |
| } |
| -bool TracingControllerImpl::StartAgentTracing( |
| - const base::trace_event::TraceConfig& trace_config) { |
| +void TracingControllerImpl::StartAgentTracing( |
| + const base::trace_event::TraceConfig& trace_config, |
| + const StartAgentTracingCallback& callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| - base::Closure on_start_tracing_done_callback = |
| - base::Bind(&TracingControllerImpl::OnStartAgentTracingDone, |
| - base::Unretained(this), trace_config); |
| + base::Closure on_agent_started = |
| + base::Bind(callback, kChromeTracingAgentName, true); |
| if (!BrowserThread::PostTask( |
| BrowserThread::FILE, FROM_HERE, |
| base::Bind(&TracingControllerImpl::SetEnabledOnFileThread, |
| base::Unretained(this), trace_config, |
| base::trace_event::TraceLog::RECORDING_MODE, |
| - on_start_tracing_done_callback))) { |
| + on_agent_started))) { |
| // BrowserThread::PostTask fails if the threads haven't been created yet, |
| // so it should be safe to just use TraceLog::SetEnabled directly. |
| base::trace_event::TraceLog::GetInstance()->SetEnabled( |
| trace_config, base::trace_event::TraceLog::RECORDING_MODE); |
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - on_start_tracing_done_callback); |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, on_agent_started); |
| } |
| - |
| - return true; |
| } |
| void TracingControllerImpl::StopAgentTracing( |