summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/trace_event/trace_event_impl.cc40
-rw-r--r--base/trace_event/trace_event_impl.h13
-rw-r--r--base/trace_event/trace_event_unittest.cc26
-rw-r--r--components/tracing/child_trace_message_filter.cc6
-rw-r--r--components/tracing/child_trace_message_filter.h1
-rw-r--r--components/tracing/tracing_messages.h3
-rw-r--r--content/browser/tracing/trace_message_filter.cc7
-rw-r--r--content/browser/tracing/trace_message_filter.h1
-rw-r--r--content/browser/tracing/tracing_controller_impl.cc28
9 files changed, 106 insertions, 19 deletions
diff --git a/base/trace_event/trace_event_impl.cc b/base/trace_event/trace_event_impl.cc
index 8051605..3925710 100644
--- a/base/trace_event/trace_event_impl.cc
+++ b/base/trace_event/trace_event_impl.cc
@@ -1769,6 +1769,17 @@ void TraceLog::SetEventCallbackDisabled() {
// 4. If any thread hasn't finish its flush in time, finish the flush.
void TraceLog::Flush(const TraceLog::OutputCallback& cb,
bool use_worker_thread) {
+ FlushInternal(cb, use_worker_thread, false);
+}
+
+void TraceLog::CancelTracing(const OutputCallback& cb) {
+ SetDisabled();
+ FlushInternal(cb, false, true);
+}
+
+void TraceLog::FlushInternal(const TraceLog::OutputCallback& cb,
+ bool use_worker_thread,
+ bool discard_events) {
use_worker_thread_ = use_worker_thread;
if (IsEnabled()) {
// Can't flush when tracing is enabled because otherwise PostTask would
@@ -1812,17 +1823,17 @@ void TraceLog::Flush(const TraceLog::OutputCallback& cb,
if (thread_message_loop_task_runners.size()) {
for (size_t i = 0; i < thread_message_loop_task_runners.size(); ++i) {
thread_message_loop_task_runners[i]->PostTask(
- FROM_HERE,
- Bind(&TraceLog::FlushCurrentThread, Unretained(this), generation));
+ FROM_HERE, Bind(&TraceLog::FlushCurrentThread, Unretained(this),
+ generation, discard_events));
}
flush_task_runner_->PostDelayedTask(
- FROM_HERE,
- Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation),
+ FROM_HERE, Bind(&TraceLog::OnFlushTimeout, Unretained(this), generation,
+ discard_events),
TimeDelta::FromMilliseconds(kThreadFlushTimeoutMs));
return;
}
- FinishFlush(generation);
+ FinishFlush(generation, discard_events);
}
// Usually it runs on a different thread.
@@ -1852,7 +1863,7 @@ void TraceLog::ConvertTraceEventsToTraceFormat(
flush_output_callback.Run(json_events_str_ptr, false);
}
-void TraceLog::FinishFlush(int generation) {
+void TraceLog::FinishFlush(int generation, bool discard_events) {
scoped_ptr<TraceBuffer> previous_logged_events;
OutputCallback flush_output_callback;
TraceEvent::ArgumentFilterPredicate argument_filter_predicate;
@@ -1877,6 +1888,14 @@ void TraceLog::FinishFlush(int generation) {
}
}
+ if (discard_events) {
+ if (!flush_output_callback.is_null()) {
+ scoped_refptr<RefCountedString> empty_result = new RefCountedString;
+ flush_output_callback.Run(empty_result, false);
+ }
+ return;
+ }
+
if (use_worker_thread_ &&
WorkerPool::PostTask(
FROM_HERE, Bind(&TraceLog::ConvertTraceEventsToTraceFormat,
@@ -1892,7 +1911,7 @@ void TraceLog::FinishFlush(int generation) {
}
// Run in each thread holding a local event buffer.
-void TraceLog::FlushCurrentThread(int generation) {
+void TraceLog::FlushCurrentThread(int generation, bool discard_events) {
{
AutoLock lock(lock_);
if (!CheckGeneration(generation) || !flush_task_runner_) {
@@ -1910,10 +1929,11 @@ void TraceLog::FlushCurrentThread(int generation) {
return;
flush_task_runner_->PostTask(
- FROM_HERE, Bind(&TraceLog::FinishFlush, Unretained(this), generation));
+ FROM_HERE, Bind(&TraceLog::FinishFlush, Unretained(this), generation,
+ discard_events));
}
-void TraceLog::OnFlushTimeout(int generation) {
+void TraceLog::OnFlushTimeout(int generation, bool discard_events) {
{
AutoLock lock(lock_);
if (!CheckGeneration(generation) || !flush_task_runner_) {
@@ -1932,7 +1952,7 @@ void TraceLog::OnFlushTimeout(int generation) {
LOG(WARNING) << "Thread: " << (*it)->thread_name();
}
}
- FinishFlush(generation);
+ FinishFlush(generation, discard_events);
}
void TraceLog::FlushButLeaveBufferIntact(
diff --git a/base/trace_event/trace_event_impl.h b/base/trace_event/trace_event_impl.h
index 2922840..ccb8500 100644
--- a/base/trace_event/trace_event_impl.h
+++ b/base/trace_event/trace_event_impl.h
@@ -428,6 +428,9 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
void Flush(const OutputCallback& cb, bool use_worker_thread = false);
void FlushButLeaveBufferIntact(const OutputCallback& flush_output_callback);
+ // Cancels tracing and discards collected data.
+ void CancelTracing(const OutputCallback& cb);
+
// Called by TRACE_EVENT* macros, don't call this directly.
// The name parameter is a category group for example:
// TRACE_EVENT0("renderer,webkit", "WebViewImpl::HandleInputEvent")
@@ -596,16 +599,20 @@ class BASE_EXPORT TraceLog : public MemoryDumpProvider {
TraceEvent* GetEventByHandleInternal(TraceEventHandle handle,
OptionalAutoLock* lock);
+ void FlushInternal(const OutputCallback& cb,
+ bool use_worker_thread,
+ bool discard_events);
+
// |generation| is used in the following callbacks to check if the callback
// is called for the flush of the current |logged_events_|.
- void FlushCurrentThread(int generation);
+ void FlushCurrentThread(int generation, bool discard_events);
// Usually it runs on a different thread.
static void ConvertTraceEventsToTraceFormat(
scoped_ptr<TraceBuffer> logged_events,
const TraceLog::OutputCallback& flush_output_callback,
const TraceEvent::ArgumentFilterPredicate& argument_filter_predicate);
- void FinishFlush(int generation);
- void OnFlushTimeout(int generation);
+ void FinishFlush(int generation, bool discard_events);
+ void OnFlushTimeout(int generation, bool discard_events);
int generation() const {
return static_cast<int>(subtle::NoBarrier_Load(&generation_));
diff --git a/base/trace_event/trace_event_unittest.cc b/base/trace_event/trace_event_unittest.cc
index 1827aa8..d648129 100644
--- a/base/trace_event/trace_event_unittest.cc
+++ b/base/trace_event/trace_event_unittest.cc
@@ -87,6 +87,12 @@ class TraceEventTestFixture : public testing::Test {
TraceLog::RECORDING_MODE);
}
+ void CancelTrace() {
+ WaitableEvent flush_complete_event(false, false);
+ CancelTraceAsync(&flush_complete_event);
+ flush_complete_event.Wait();
+ }
+
void EndTraceAndFlush() {
num_flush_callbacks_ = 0;
WaitableEvent flush_complete_event(false, false);
@@ -106,6 +112,13 @@ class TraceEventTestFixture : public testing::Test {
flush_complete_event.Wait();
}
+ void CancelTraceAsync(WaitableEvent* flush_complete_event) {
+ TraceLog::GetInstance()->CancelTracing(
+ base::Bind(&TraceEventTestFixture::OnTraceDataCollected,
+ base::Unretained(static_cast<TraceEventTestFixture*>(this)),
+ base::Unretained(flush_complete_event)));
+ }
+
void EndTraceAndFlushAsync(WaitableEvent* flush_complete_event) {
TraceLog::GetInstance()->SetDisabled();
TraceLog::GetInstance()->Flush(
@@ -908,6 +921,19 @@ TEST_F(TraceEventTestFixture, DataCaptured) {
ValidateAllTraceMacrosCreatedData(trace_parsed_);
}
+// Emit some events and validate that only empty strings are received
+// if we tell Flush() to discard events.
+TEST_F(TraceEventTestFixture, DataDiscarded) {
+ TraceLog::GetInstance()->SetEnabled(TraceConfig(kRecordAllCategoryFilter, ""),
+ TraceLog::RECORDING_MODE);
+
+ TraceWithAllMacroVariants(NULL);
+
+ CancelTrace();
+
+ EXPECT_TRUE(trace_parsed_.empty());
+}
+
class MockEnabledStateChangedObserver :
public TraceLog::EnabledStateObserver {
public:
diff --git a/components/tracing/child_trace_message_filter.cc b/components/tracing/child_trace_message_filter.cc
index ad34a24..b3babc2 100644
--- a/components/tracing/child_trace_message_filter.cc
+++ b/components/tracing/child_trace_message_filter.cc
@@ -38,6 +38,7 @@ bool ChildTraceMessageFilter::OnMessageReceived(const IPC::Message& message) {
IPC_BEGIN_MESSAGE_MAP(ChildTraceMessageFilter, message)
IPC_MESSAGE_HANDLER(TracingMsg_BeginTracing, OnBeginTracing)
IPC_MESSAGE_HANDLER(TracingMsg_EndTracing, OnEndTracing)
+ IPC_MESSAGE_HANDLER(TracingMsg_CancelTracing, OnCancelTracing)
IPC_MESSAGE_HANDLER(TracingMsg_EnableMonitoring, OnEnableMonitoring)
IPC_MESSAGE_HANDLER(TracingMsg_DisableMonitoring, OnDisableMonitoring)
IPC_MESSAGE_HANDLER(TracingMsg_CaptureMonitoringSnapshot,
@@ -82,6 +83,11 @@ void ChildTraceMessageFilter::OnEndTracing() {
base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this));
}
+void ChildTraceMessageFilter::OnCancelTracing() {
+ TraceLog::GetInstance()->CancelTracing(
+ base::Bind(&ChildTraceMessageFilter::OnTraceDataCollected, this));
+}
+
void ChildTraceMessageFilter::OnEnableMonitoring(
const std::string& trace_config_str,
base::TraceTicks browser_time) {
diff --git a/components/tracing/child_trace_message_filter.h b/components/tracing/child_trace_message_filter.h
index 494d25d..a075edb 100644
--- a/components/tracing/child_trace_message_filter.h
+++ b/components/tracing/child_trace_message_filter.h
@@ -43,6 +43,7 @@ class ChildTraceMessageFilter : public IPC::MessageFilter {
void OnBeginTracing(const std::string& trace_config_str,
base::TraceTicks browser_time);
void OnEndTracing();
+ void OnCancelTracing();
void OnEnableMonitoring(const std::string& trace_config_str,
base::TraceTicks browser_time);
void OnDisableMonitoring();
diff --git a/components/tracing/tracing_messages.h b/components/tracing/tracing_messages.h
index 14f31bb..ebdefc1 100644
--- a/components/tracing/tracing_messages.h
+++ b/components/tracing/tracing_messages.h
@@ -39,6 +39,9 @@ IPC_MESSAGE_CONTROL2(TracingMsg_BeginTracing,
// Sent to all child processes to disable trace event recording.
IPC_MESSAGE_CONTROL0(TracingMsg_EndTracing)
+// Sent to all child processes to cancel trace event recording.
+IPC_MESSAGE_CONTROL0(TracingMsg_CancelTracing)
+
// Sent to all child processes to start monitoring.
IPC_MESSAGE_CONTROL2(TracingMsg_EnableMonitoring,
std::string /* trace_config_str */,
diff --git a/content/browser/tracing/trace_message_filter.cc b/content/browser/tracing/trace_message_filter.cc
index 1ded8e5..6d48523 100644
--- a/content/browser/tracing/trace_message_filter.cc
+++ b/content/browser/tracing/trace_message_filter.cc
@@ -74,6 +74,13 @@ void TraceMessageFilter::SendEndTracing() {
Send(new TracingMsg_EndTracing);
}
+void TraceMessageFilter::SendCancelTracing() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ DCHECK(!is_awaiting_end_ack_);
+ is_awaiting_end_ack_ = true;
+ Send(new TracingMsg_CancelTracing);
+}
+
void TraceMessageFilter::SendEnableMonitoring(
const base::trace_event::TraceConfig& trace_config) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/tracing/trace_message_filter.h b/content/browser/tracing/trace_message_filter.h
index 0d1f05c..3bc7ccc 100644
--- a/content/browser/tracing/trace_message_filter.h
+++ b/content/browser/tracing/trace_message_filter.h
@@ -28,6 +28,7 @@ class TraceMessageFilter : public BrowserMessageFilter {
void SendBeginTracing(
const base::trace_event::TraceConfig& trace_config);
void SendEndTracing();
+ void SendCancelTracing();
void SendEnableMonitoring(
const base::trace_event::TraceConfig& trace_config);
void SendDisableMonitoring();
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc
index 5c94a0b..ce9b854 100644
--- a/content/browser/tracing/tracing_controller_impl.cc
+++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -231,17 +231,27 @@ void TracingControllerImpl::OnDisableRecordingDone() {
// trace log. Once the flush has completed the caller will be notified that
// tracing has ended.
if (pending_disable_recording_ack_count_ == 1) {
- // Flush asynchronously now, because we don't have any children to wait for.
- TraceLog::GetInstance()->Flush(
- base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
- base::Unretained(this)),
- true);
+ // Flush/cancel asynchronously now, because we don't have any children to
+ // wait for.
+ if (trace_data_sink_) {
+ TraceLog::GetInstance()->Flush(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)),
+ true);
+ } else {
+ TraceLog::GetInstance()->CancelTracing(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)));
+ }
}
// Notify all child processes.
for (TraceMessageFilterSet::iterator it = trace_message_filters_.begin();
it != trace_message_filters_.end(); ++it) {
- it->get()->SendEndTracing();
+ if (trace_data_sink_)
+ it->get()->SendEndTracing();
+ else
+ it->get()->SendCancelTracing();
}
}
@@ -566,10 +576,16 @@ void TracingControllerImpl::OnDisableRecordingAcked(
// All acks from subprocesses have been received. Now flush the local trace.
// During or after this call, our OnLocalTraceDataCollected will be
// called with the last of the local trace data.
+ if (trace_data_sink_) {
TraceLog::GetInstance()->Flush(
base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
base::Unretained(this)),
true);
+ } else {
+ TraceLog::GetInstance()->CancelTracing(
+ base::Bind(&TracingControllerImpl::OnLocalTraceDataCollected,
+ base::Unretained(this)));
+ }
return;
}