Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(319)

Side by Side Diff: content/browser/trace_controller_impl.cc

Issue 10837082: implement SetWatchEvent and WaitForEvent for trace-based-tests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update / merge -- no change Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/trace_controller_impl.h ('k') | content/browser/trace_message_filter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/trace_controller_impl.h" 5 #include "content/browser/trace_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/string_number_conversions.h" 10 #include "base/string_number_conversions.h"
11 #include "content/browser/trace_message_filter.h" 11 #include "content/browser/trace_message_filter.h"
12 #include "content/browser/trace_subscriber_stdio.h" 12 #include "content/browser/trace_subscriber_stdio.h"
13 #include "content/common/child_process_messages.h" 13 #include "content/common/child_process_messages.h"
14 #include "content/public/browser/browser_message_filter.h" 14 #include "content/public/browser/browser_message_filter.h"
15 #include "content/public/common/content_switches.h" 15 #include "content/public/common/content_switches.h"
16 16
17 using base::debug::TraceLog; 17 using base::debug::TraceLog;
18 18
19 namespace content { 19 namespace content {
20 20
21 namespace { 21 namespace {
22 22
23 base::LazyInstance<TraceControllerImpl>::Leaky g_controller =
24 LAZY_INSTANCE_INITIALIZER;
25
23 class AutoStopTraceSubscriberStdio : public content::TraceSubscriberStdio { 26 class AutoStopTraceSubscriberStdio : public content::TraceSubscriberStdio {
24 public: 27 public:
25 AutoStopTraceSubscriberStdio(const FilePath& file_path) 28 AutoStopTraceSubscriberStdio(const FilePath& file_path)
26 : TraceSubscriberStdio(file_path) {} 29 : TraceSubscriberStdio(file_path) {}
27 30
28 static void EndStartupTrace(TraceSubscriberStdio* subscriber) { 31 static void EndStartupTrace(TraceSubscriberStdio* subscriber) {
29 if (!TraceControllerImpl::GetInstance()->EndTracingAsync(subscriber)) 32 if (!TraceControllerImpl::GetInstance()->EndTracingAsync(subscriber))
30 delete subscriber; 33 delete subscriber;
31 // else, the tracing will end asynchronously in OnEndTracingComplete(). 34 // else, the tracing will end asynchronously in OnEndTracingComplete().
32 } 35 }
(...skipping 12 matching lines...) Expand all
45 return TraceControllerImpl::GetInstance(); 48 return TraceControllerImpl::GetInstance();
46 } 49 }
47 50
48 TraceControllerImpl::TraceControllerImpl() : 51 TraceControllerImpl::TraceControllerImpl() :
49 subscriber_(NULL), 52 subscriber_(NULL),
50 pending_end_ack_count_(0), 53 pending_end_ack_count_(0),
51 pending_bpf_ack_count_(0), 54 pending_bpf_ack_count_(0),
52 maximum_bpf_(0.0f), 55 maximum_bpf_(0.0f),
53 is_tracing_(false), 56 is_tracing_(false),
54 is_get_categories_(false) { 57 is_get_categories_(false) {
55 TraceLog::GetInstance()->SetOutputCallback( 58 TraceLog::GetInstance()->SetNotificationCallback(
56 base::Bind(&TraceControllerImpl::OnTraceDataCollected, 59 base::Bind(&TraceControllerImpl::OnTraceNotification,
57 base::Unretained(this))); 60 base::Unretained(this)));
58 } 61 }
59 62
60 TraceControllerImpl::~TraceControllerImpl() { 63 TraceControllerImpl::~TraceControllerImpl() {
61 if (TraceLog* trace_log = TraceLog::GetInstance()) 64 // No need to SetNotificationCallback(nil) on the TraceLog since this is a
62 trace_log->SetOutputCallback(TraceLog::OutputCallback()); 65 // Leaky instance.
66 NOTREACHED();
63 } 67 }
64 68
65 TraceControllerImpl* TraceControllerImpl::GetInstance() { 69 TraceControllerImpl* TraceControllerImpl::GetInstance() {
66 return Singleton<TraceControllerImpl>::get(); 70 return g_controller.Pointer();
67 } 71 }
68 72
69 void TraceControllerImpl::InitStartupTracing(const CommandLine& command_line) { 73 void TraceControllerImpl::InitStartupTracing(const CommandLine& command_line) {
70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
71 FilePath trace_file = command_line.GetSwitchValuePath( 75 FilePath trace_file = command_line.GetSwitchValuePath(
72 switches::kTraceStartupFile); 76 switches::kTraceStartupFile);
73 // trace_file = "none" means that startup events will show up for the next 77 // trace_file = "none" means that startup events will show up for the next
74 // begin/end tracing (via about:tracing or AutomationProxy::BeginTracing/ 78 // begin/end tracing (via about:tracing or AutomationProxy::BeginTracing/
75 // EndTracing, for example). 79 // EndTracing, for example).
76 if (trace_file == FilePath().AppendASCII("none")) 80 if (trace_file == FilePath().AppendASCII("none"))
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 201 }
198 202
199 // Message all child processes. 203 // Message all child processes.
200 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) { 204 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it) {
201 it->get()->SendGetTraceBufferPercentFull(); 205 it->get()->SendGetTraceBufferPercentFull();
202 } 206 }
203 207
204 return true; 208 return true;
205 } 209 }
206 210
211 bool TraceControllerImpl::SetWatchEvent(TraceSubscriber* subscriber,
212 const std::string& category_name,
213 const std::string& event_name) {
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
215 if (subscriber != subscriber_)
216 return false;
217
218 watch_category_ = category_name;
219 watch_name_ = event_name;
220
221 TraceLog::GetInstance()->SetWatchEvent(category_name, event_name);
222 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it)
223 it->get()->SendSetWatchEvent(category_name, event_name);
224
225 return true;
226 }
227
228 bool TraceControllerImpl::CancelWatchEvent(TraceSubscriber* subscriber) {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 if (subscriber != subscriber_)
231 return false;
232
233 watch_category_.clear();
234 watch_name_.clear();
235
236 TraceLog::GetInstance()->CancelWatchEvent();
237 for (FilterMap::iterator it = filters_.begin(); it != filters_.end(); ++it)
238 it->get()->SendCancelWatchEvent();
239
240 return true;
241 }
242
207 void TraceControllerImpl::CancelSubscriber(TraceSubscriber* subscriber) { 243 void TraceControllerImpl::CancelSubscriber(TraceSubscriber* subscriber) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 244 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 245
210 if (subscriber == subscriber_) { 246 if (subscriber == subscriber_) {
211 subscriber_ = NULL; 247 subscriber_ = NULL;
212 // End tracing if necessary. 248 // End tracing if necessary.
213 if (is_tracing_ && pending_end_ack_count_ == 0) 249 if (is_tracing_ && pending_end_ack_count_ == 0)
214 EndTracingAsync(NULL); 250 EndTracingAsync(NULL);
215 } 251 }
216 } 252 }
217 253
218 void TraceControllerImpl::AddFilter(TraceMessageFilter* filter) { 254 void TraceControllerImpl::AddFilter(TraceMessageFilter* filter) {
219 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 255 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
220 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 256 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
221 base::Bind(&TraceControllerImpl::AddFilter, base::Unretained(this), 257 base::Bind(&TraceControllerImpl::AddFilter, base::Unretained(this),
222 make_scoped_refptr(filter))); 258 make_scoped_refptr(filter)));
223 return; 259 return;
224 } 260 }
225 261
226 filters_.insert(filter); 262 filters_.insert(filter);
227 if (is_tracing_enabled()) { 263 if (is_tracing_enabled()) {
228 filter->SendBeginTracing(included_categories_, excluded_categories_); 264 filter->SendBeginTracing(included_categories_, excluded_categories_);
265 if (!watch_category_.empty())
266 filter->SendSetWatchEvent(watch_category_, watch_name_);
229 } 267 }
230 } 268 }
231 269
232 void TraceControllerImpl::RemoveFilter(TraceMessageFilter* filter) { 270 void TraceControllerImpl::RemoveFilter(TraceMessageFilter* filter) {
233 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 271 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
234 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 272 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
235 base::Bind(&TraceControllerImpl::RemoveFilter, base::Unretained(this), 273 base::Bind(&TraceControllerImpl::RemoveFilter, base::Unretained(this),
236 make_scoped_refptr(filter))); 274 make_scoped_refptr(filter)));
237 return; 275 return;
238 } 276 }
(...skipping 26 matching lines...) Expand all
265 // Merge known_categories with known_categories_ 303 // Merge known_categories with known_categories_
266 known_categories_.insert(known_categories.begin(), known_categories.end()); 304 known_categories_.insert(known_categories.begin(), known_categories.end());
267 305
268 if (pending_end_ack_count_ == 0) 306 if (pending_end_ack_count_ == 0)
269 return; 307 return;
270 308
271 if (--pending_end_ack_count_ == 0) { 309 if (--pending_end_ack_count_ == 0) {
272 // All acks have been received. 310 // All acks have been received.
273 is_tracing_ = false; 311 is_tracing_ = false;
274 312
275 // Disable local trace. During this call, our OnTraceDataCollected will be 313 // Disable local trace.
314 TraceLog::GetInstance()->SetDisabled();
315
316 // During this call, our OnTraceDataCollected will be
276 // called with the last of the local trace data. Since we are on the UI 317 // called with the last of the local trace data. Since we are on the UI
277 // thread, the call to OnTraceDataCollected will be synchronous, so we can 318 // thread, the call to OnTraceDataCollected will be synchronous, so we can
278 // immediately call OnEndTracingComplete below. 319 // immediately call OnEndTracingComplete below.
279 TraceLog::GetInstance()->SetEnabled(false); 320 TraceLog::GetInstance()->Flush(
321 base::Bind(&TraceControllerImpl::OnTraceDataCollected,
322 base::Unretained(this)));
280 323
281 // Trigger callback if one is set. 324 // Trigger callback if one is set.
282 if (subscriber_) { 325 if (subscriber_) {
283 if (is_get_categories_) 326 if (is_get_categories_)
284 subscriber_->OnKnownCategoriesCollected(known_categories_); 327 subscriber_->OnKnownCategoriesCollected(known_categories_);
285 else 328 else
286 subscriber_->OnEndTracingComplete(); 329 subscriber_->OnEndTracingComplete();
287 // Clear subscriber so that others can use TraceController. 330 // Clear subscriber so that others can use TraceController.
288 subscriber_ = NULL; 331 subscriber_ = NULL;
289 } 332 }
(...skipping 21 matching lines...) Expand all
311 base::Bind(&TraceControllerImpl::OnTraceDataCollected, 354 base::Bind(&TraceControllerImpl::OnTraceDataCollected,
312 base::Unretained(this), events_str_ptr)); 355 base::Unretained(this), events_str_ptr));
313 return; 356 return;
314 } 357 }
315 358
316 // Drop trace events if we are just getting categories. 359 // Drop trace events if we are just getting categories.
317 if (subscriber_ && !is_get_categories_) 360 if (subscriber_ && !is_get_categories_)
318 subscriber_->OnTraceDataCollected(events_str_ptr); 361 subscriber_->OnTraceDataCollected(events_str_ptr);
319 } 362 }
320 363
321 void TraceControllerImpl::OnTraceBufferFull() { 364 void TraceControllerImpl::OnTraceNotification(int notification) {
322 // OnTraceBufferFull may be called from any browser thread, either by the 365 // OnTraceNotification may be called from any browser thread, either by the
323 // local event trace system or from child processes via TraceMessageFilter. 366 // local event trace system or from child processes via TraceMessageFilter.
324 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 367 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
325 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 368 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
326 base::Bind(&TraceControllerImpl::OnTraceBufferFull, 369 base::Bind(&TraceControllerImpl::OnTraceNotification,
327 base::Unretained(this))); 370 base::Unretained(this), notification));
328 return; 371 return;
329 } 372 }
330 373
331 // EndTracingAsync may return false if tracing is already in the process of 374 if (notification & base::debug::TraceLog::TRACE_BUFFER_FULL) {
332 // being ended. That is ok. 375 // EndTracingAsync may return false if tracing is already in the process
333 EndTracingAsync(subscriber_); 376 // of being ended. That is ok.
377 EndTracingAsync(subscriber_);
378 }
379 if (notification & base::debug::TraceLog::EVENT_WATCH_NOTIFICATION) {
380 if (subscriber_)
381 subscriber_->OnEventWatchNotification();
382 }
334 } 383 }
335 384
336 void TraceControllerImpl::OnTraceBufferPercentFullReply(float percent_full) { 385 void TraceControllerImpl::OnTraceBufferPercentFullReply(float percent_full) {
337 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { 386 if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
338 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 387 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
339 base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply, 388 base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
340 base::Unretained(this), percent_full)); 389 base::Unretained(this), percent_full));
341 return; 390 return;
342 } 391 }
343 392
(...skipping 12 matching lines...) Expand all
356 // The last ack represents local trace, so we need to ack it now. Note that 405 // The last ack represents local trace, so we need to ack it now. Note that
357 // this code only executes if there were child processes. 406 // this code only executes if there were child processes.
358 float bpf = TraceLog::GetInstance()->GetBufferPercentFull(); 407 float bpf = TraceLog::GetInstance()->GetBufferPercentFull();
359 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 408 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
360 base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply, 409 base::Bind(&TraceControllerImpl::OnTraceBufferPercentFullReply,
361 base::Unretained(this), bpf)); 410 base::Unretained(this), bpf));
362 } 411 }
363 } 412 }
364 413
365 } // namespace content 414 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/trace_controller_impl.h ('k') | content/browser/trace_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698