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