Chromium Code Reviews| Index: content/browser/trace_controller_impl.cc |
| diff --git a/content/browser/trace_controller_impl.cc b/content/browser/trace_controller_impl.cc |
| index 0c5d5cdfbb5a9598e1ce963956dcaa23578f3d5b..0968561dc4c4caa6282ea3d83a2945016261b91b 100644 |
| --- a/content/browser/trace_controller_impl.cc |
| +++ b/content/browser/trace_controller_impl.cc |
| @@ -51,15 +51,16 @@ TraceControllerImpl::TraceControllerImpl() : |
| pending_bpf_ack_count_(0), |
| maximum_bpf_(0.0f), |
| is_tracing_(false), |
| - is_get_categories_(false) { |
| - TraceLog::GetInstance()->SetOutputCallback( |
| - base::Bind(&TraceControllerImpl::OnTraceDataCollected, |
| + is_get_categories_(false), |
| + watch_num_occurrences_(0) { |
| + TraceLog::GetInstance()->SetNotificationCallback( |
| + base::Bind(&TraceControllerImpl::OnTraceNotification, |
| base::Unretained(this))); |
| } |
| TraceControllerImpl::~TraceControllerImpl() { |
| if (TraceLog* trace_log = TraceLog::GetInstance()) |
| - trace_log->SetOutputCallback(TraceLog::OutputCallback()); |
| + trace_log->SetNotificationCallback(TraceLog::NotificationCallback()); |
| } |
| TraceControllerImpl* TraceControllerImpl::GetInstance() { |
| @@ -210,6 +211,42 @@ bool TraceControllerImpl::GetTraceBufferPercentFullAsync( |
| return true; |
| } |
| +bool TraceControllerImpl::SetWatchEvent(TraceSubscriber* subscriber, |
| + const char* category_name, |
| + const char* event_name, |
| + int num_occurrences) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (subscriber != subscriber_) |
| + return false; |
| + |
| + watch_num_occurrences_ = num_occurrences; |
| + watch_category_ = category_name; |
| + watch_name_ = event_name; |
| + |
| + TraceLog::GetInstance()->SetWatchEvent(category_name, event_name, |
| + num_occurrences); |
| + for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) |
| + it->get()->SendSetWatchEvent(category_name, event_name, num_occurrences); |
| + |
| + return true; |
| +} |
| + |
| +bool TraceControllerImpl::CancelWatchEvent(TraceSubscriber* subscriber) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (subscriber != subscriber_) |
| + return false; |
| + |
| + watch_num_occurrences_ = 0; |
| + watch_category_.clear(); |
| + watch_name_.clear(); |
| + |
| + TraceLog::GetInstance()->CancelWatchEvent(); |
| + for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) |
| + it->get()->SendCancelWatchEvent(); |
| + |
| + return true; |
| +} |
| + |
| void TraceControllerImpl::CancelSubscriber(TraceSubscriber* subscriber) { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| @@ -232,6 +269,10 @@ void TraceControllerImpl::AddFilter(TraceMessageFilter* filter) { |
| filters_.insert(filter); |
| if (is_tracing_enabled()) { |
| filter->SendBeginTracing(included_categories_, excluded_categories_); |
| + if (watch_num_occurrences_ > 0) { |
| + filter->SendSetWatchEvent(watch_category_, watch_name_, |
| + watch_num_occurrences_); |
| + } |
| } |
| } |
| @@ -278,11 +319,16 @@ void TraceControllerImpl::OnEndTracingAck( |
| // All acks have been received. |
| is_tracing_ = false; |
| - // Disable local trace. During this call, our OnTraceDataCollected will be |
| + // Disable local trace. |
| + TraceLog::GetInstance()->SetDisabled(); |
| + |
| + // During this call, our OnTraceDataCollected will be |
| // called with the last of the local trace data. Since we are on the UI |
| // thread, the call to OnTraceDataCollected will be synchronous, so we can |
| // immediately call OnEndTracingComplete below. |
| - TraceLog::GetInstance()->SetEnabled(false); |
| + TraceLog::GetInstance()->Flush( |
| + base::Bind(&TraceControllerImpl::OnTraceDataCollected, |
| + base::Unretained(this))); |
| // Trigger callback if one is set. |
| if (subscriber_) { |
| @@ -324,19 +370,27 @@ void TraceControllerImpl::OnTraceDataCollected( |
| subscriber_->OnTraceDataCollected(events_str_ptr); |
| } |
| -void TraceControllerImpl::OnTraceBufferFull() { |
| - // OnTraceBufferFull may be called from any browser thread, either by the |
| +void TraceControllerImpl::OnTraceNotification(int notification) { |
| + // OnTraceNotification may be called from any browser thread, either by the |
| // local event trace system or from child processes via TraceMessageFilter. |
| if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
| BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| - base::Bind(&TraceControllerImpl::OnTraceBufferFull, |
| - base::Unretained(this))); |
| + base::Bind(&TraceControllerImpl::OnTraceNotification, |
| + base::Unretained(this), notification)); |
| return; |
| } |
| - // EndTracingAsync may return false if tracing is already in the process of |
| - // being ended. That is ok. |
| - EndTracingAsync(subscriber_); |
| + switch (static_cast<base::debug::TraceLog::Notification>(notification)) { |
|
ccameron
2012/08/21 01:06:34
The definition of ...::Notification says that the
jbates
2012/08/23 22:45:28
Good catch, fixed this code to check for both flag
|
| + case base::debug::TraceLog::TRACE_BUFFER_FULL: |
| + // EndTracingAsync may return false if tracing is already in the process |
| + // of being ended. That is ok. |
| + EndTracingAsync(subscriber_); |
| + break; |
| + case base::debug::TraceLog::EVENT_WATCH_NOTIFICATION: |
| + if (subscriber_) |
| + subscriber_->OnEventWatchNotification(); |
| + break; |
| + } |
| } |
| void TraceControllerImpl::OnTraceBufferPercentFullReply(float percent_full) { |