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

Side by Side Diff: base/message_loop/message_pump_mac.mm

Issue 360373004: Revert 221427 "Add instrumentation to the MessagePumpMac family ..." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 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 | « base/message_loop/message_pump_mac.h ('k') | no next file » | 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 #import "base/message_loop/message_pump_mac.h" 5 #import "base/message_loop/message_pump_mac.h"
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 #import <Foundation/Foundation.h> 8 #import <Foundation/Foundation.h>
9 9
10 #include <limits> 10 #include <limits>
11 #include <stack>
12 11
13 #include "base/format_macros.h"
14 #include "base/logging.h" 12 #include "base/logging.h"
15 #include "base/mac/scoped_cftyperef.h" 13 #include "base/mac/scoped_cftyperef.h"
16 #include "base/message_loop/timer_slack.h" 14 #include "base/message_loop/timer_slack.h"
17 #include "base/metrics/histogram.h"
18 #include "base/run_loop.h" 15 #include "base/run_loop.h"
19 #include "base/strings/stringprintf.h"
20 #include "base/time/time.h" 16 #include "base/time/time.h"
21 17
22 #if !defined(OS_IOS) 18 #if !defined(OS_IOS)
23 #import <AppKit/AppKit.h> 19 #import <AppKit/AppKit.h>
24 #endif // !defined(OS_IOS) 20 #endif // !defined(OS_IOS)
25 21
26 namespace base { 22 namespace base {
27 23
28 namespace { 24 namespace {
29 25
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 112 }
117 ~MessagePumpScopedAutoreleasePool() { 113 ~MessagePumpScopedAutoreleasePool() {
118 [pool_ drain]; 114 [pool_ drain];
119 } 115 }
120 116
121 private: 117 private:
122 NSAutoreleasePool* pool_; 118 NSAutoreleasePool* pool_;
123 DISALLOW_COPY_AND_ASSIGN(MessagePumpScopedAutoreleasePool); 119 DISALLOW_COPY_AND_ASSIGN(MessagePumpScopedAutoreleasePool);
124 }; 120 };
125 121
126 // This class is used to instrument the MessagePump to gather various timing
127 // data about when the underlying run loop is entered, when it is waiting, and
128 // when it is servicing its delegate.
129 //
130 // The metrics are gathered as UMA-tracked histograms. To gather the data over
131 // time, sampling is used, such that a new histogram is created for each metric
132 // every |sampling_interval| for |sampling_duration|. After sampling is
133 // complete, this class deletes itself.
134 class MessagePumpInstrumentation {
135 public:
136 // Creates an instrument for the MessagePump on the current thread. Every
137 // |sampling_interval|, a new histogram will be created to track the metrics
138 // over time. After |sampling_duration|, this will delete itself, causing the
139 // WeakPtr to go NULL.
140 static WeakPtr<MessagePumpInstrumentation> Create(
141 const TimeDelta& sampling_interval,
142 const TimeDelta& sampling_duration) {
143 MessagePumpInstrumentation* instrument =
144 new MessagePumpInstrumentation(sampling_interval, sampling_duration);
145 return instrument->weak_ptr_factory_.GetWeakPtr();
146 }
147
148 // Starts the timer that runs the sampling instrumentation. Can be called
149 // multiple times as a noop.
150 void StartIfNeeded() {
151 if (timer_)
152 return;
153
154 sampling_start_time_ = generation_start_time_ = TimeTicks::Now();
155
156 CFRunLoopTimerContext timer_context = { .info = this };
157 timer_.reset(CFRunLoopTimerCreate(
158 NULL, // allocator
159 (Time::Now() + sampling_interval_).ToCFAbsoluteTime(),
160 sampling_interval_.InSecondsF(),
161 0, // flags
162 0, // order
163 &MessagePumpInstrumentation::TimerFired,
164 &timer_context));
165 CFRunLoopAddTimerToAllModes(CFRunLoopGetCurrent(), timer_);
166 }
167
168 // Used to track kCFRunLoopEntry.
169 void LoopEntered() {
170 loop_run_times_.push(TimeTicks::Now());
171 }
172
173 // Used to track kCFRunLoopExit.
174 void LoopExited() {
175 TimeDelta duration = TimeTicks::Now() - loop_run_times_.top();
176 loop_run_times_.pop();
177 GetHistogram(LOOP_CYCLE)->AddTime(duration);
178 }
179
180 // Used to track kCFRunLoopBeforeWaiting.
181 void WaitingStarted() {
182 loop_wait_times_.push(TimeTicks::Now());
183 }
184
185 // Used to track kCFRunLoopAfterWaiting.
186 void WaitingFinished() {
187 TimeDelta duration = TimeTicks::Now() - loop_wait_times_.top();
188 loop_wait_times_.pop();
189 GetHistogram(LOOP_WAIT)->AddTime(duration);
190 }
191
192 // Used to track when the MessagePump will invoke its |delegate|.
193 void WorkSourceEntered(MessagePump::Delegate* delegate) {
194 work_source_times_.push(TimeTicks::Now());
195 if (delegate) {
196 size_t queue_size;
197 TimeDelta queuing_delay;
198 delegate->GetQueueingInformation(&queue_size, &queuing_delay);
199 GetHistogram(QUEUE_SIZE)->Add(queue_size);
200 GetHistogram(QUEUE_DELAY)->AddTime(queuing_delay);
201 }
202 }
203
204 // Used to track the completion of servicing the MessagePump::Delegate.
205 void WorkSourceExited() {
206 TimeDelta duration = TimeTicks::Now() - work_source_times_.top();
207 work_source_times_.pop();
208 GetHistogram(WORK_SOURCE)->AddTime(duration);
209 }
210
211 private:
212 enum HistogramEvent {
213 // Time-based histograms:
214 LOOP_CYCLE, // LoopEntered/LoopExited
215 LOOP_WAIT, // WaitingStarted/WaitingEnded
216 WORK_SOURCE, // WorkSourceExited
217 QUEUE_DELAY, // WorkSourceEntered
218
219 // Value-based histograms:
220 // NOTE: Do not add value-based histograms before this event, only after.
221 QUEUE_SIZE, // WorkSourceEntered
222
223 HISTOGRAM_EVENT_MAX,
224 };
225
226 MessagePumpInstrumentation(const TimeDelta& sampling_interval,
227 const TimeDelta& sampling_duration)
228 : weak_ptr_factory_(this),
229 sampling_interval_(sampling_interval),
230 sampling_duration_(sampling_duration),
231 sample_generation_(0) {
232 // Create all the histogram objects that will be used for sampling.
233 const char kHistogramName[] = "MessagePumpMac.%s.SampleMs.%" PRId64;
234 for (TimeDelta i; i < sampling_duration_; i += sampling_interval_) {
235 int64 sample = i.InMilliseconds();
236
237 // Generate the time-based histograms.
238 for (int j = LOOP_CYCLE; j < QUEUE_SIZE; ++j) {
239 std::string name = StringPrintf(kHistogramName,
240 NameForEnum(static_cast<HistogramEvent>(j)), sample);
241 histograms_[j].push_back(
242 Histogram::FactoryTimeGet(name, TimeDelta::FromMilliseconds(1),
243 sampling_interval_, 50,
244 HistogramBase::kUmaTargetedHistogramFlag));
245 }
246
247 // Generate the value-based histograms.
248 for (int j = QUEUE_SIZE; j < HISTOGRAM_EVENT_MAX; ++j) {
249 std::string name = StringPrintf(kHistogramName,
250 NameForEnum(static_cast<HistogramEvent>(j)), sample);
251 histograms_[j].push_back(
252 Histogram::FactoryGet(name, 1, 10000, 50,
253 HistogramBase::kUmaTargetedHistogramFlag));
254 }
255 }
256 }
257
258 ~MessagePumpInstrumentation() {
259 if (timer_)
260 CFRunLoopTimerInvalidate(timer_);
261 }
262
263 const char* NameForEnum(HistogramEvent event) {
264 switch (event) {
265 case LOOP_CYCLE: return "LoopCycle";
266 case LOOP_WAIT: return "Waiting";
267 case WORK_SOURCE: return "WorkSource";
268 case QUEUE_DELAY: return "QueueingDelay";
269 case QUEUE_SIZE: return "QueueSize";
270 default:
271 NOTREACHED();
272 return NULL;
273 }
274 }
275
276 static void TimerFired(CFRunLoopTimerRef timer, void* context) {
277 static_cast<MessagePumpInstrumentation*>(context)->TimerFired();
278 }
279
280 // Called by the run loop when the sampling_interval_ has elapsed. Advances
281 // the sample_generation_, which controls into which histogram data is
282 // recorded, while recording and accounting for timer skew. Will delete this
283 // object after |sampling_duration_| has elapsed.
284 void TimerFired() {
285 TimeTicks now = TimeTicks::Now();
286 TimeDelta delta = now - generation_start_time_;
287
288 // The timer fired, so advance the generation by at least one.
289 ++sample_generation_;
290
291 // To account for large timer skew/drift, advance the generation by any
292 // more completed intervals.
293 for (TimeDelta skew_advance = delta - sampling_interval_;
294 skew_advance >= sampling_interval_;
295 skew_advance -= sampling_interval_) {
296 ++sample_generation_;
297 }
298
299 generation_start_time_ = now;
300 if (now >= sampling_start_time_ + sampling_duration_)
301 delete this;
302 }
303
304 HistogramBase* GetHistogram(HistogramEvent event) {
305 DCHECK_LT(sample_generation_, histograms_[event].size());
306 return histograms_[event][sample_generation_];
307 }
308
309 // Vends the pointer to the Create()or.
310 WeakPtrFactory<MessagePumpInstrumentation> weak_ptr_factory_;
311
312 // The interval and duration of the sampling.
313 TimeDelta sampling_interval_;
314 TimeDelta sampling_duration_;
315
316 // The time at which sampling started.
317 TimeTicks sampling_start_time_;
318
319 // The timer that advances the sample_generation_ and sets the
320 // generation_start_time_ for the current sample interval.
321 base::ScopedCFTypeRef<CFRunLoopTimerRef> timer_;
322
323 // The two-dimensional array of histograms. The first dimension is the
324 // HistogramEvent type. The second is for the sampling intervals.
325 std::vector<HistogramBase*> histograms_[HISTOGRAM_EVENT_MAX];
326
327 // The index in the second dimension of histograms_, which controls in which
328 // sampled histogram events are recorded.
329 size_t sample_generation_;
330
331 // The last time at which the timer fired. This is used to track timer skew
332 // (i.e. it did not fire on time) and properly account for it when advancing
333 // samle_generation_.
334 TimeTicks generation_start_time_;
335
336 // MessagePump activations can be nested. Use a stack for each of the
337 // possibly reentrant HistogramEvent types to properly balance and calculate
338 // the timing information.
339 std::stack<TimeTicks> loop_run_times_;
340 std::stack<TimeTicks> loop_wait_times_;
341 std::stack<TimeTicks> work_source_times_;
342
343 DISALLOW_COPY_AND_ASSIGN(MessagePumpInstrumentation);
344 };
345
346 // Must be called on the run loop thread. 122 // Must be called on the run loop thread.
347 MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase() 123 MessagePumpCFRunLoopBase::MessagePumpCFRunLoopBase()
348 : delegate_(NULL), 124 : delegate_(NULL),
349 delayed_work_fire_time_(kCFTimeIntervalMax), 125 delayed_work_fire_time_(kCFTimeIntervalMax),
350 timer_slack_(base::TIMER_SLACK_NONE), 126 timer_slack_(base::TIMER_SLACK_NONE),
351 nesting_level_(0), 127 nesting_level_(0),
352 run_nesting_level_(0), 128 run_nesting_level_(0),
353 deepest_nesting_level_(0), 129 deepest_nesting_level_(0),
354 delegateless_work_(false), 130 delegateless_work_(false),
355 delegateless_idle_work_(false) { 131 delegateless_idle_work_(false) {
(...skipping 30 matching lines...) Expand all
386 162
387 source_context.perform = RunNestingDeferredWorkSource; 163 source_context.perform = RunNestingDeferredWorkSource;
388 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator 164 nesting_deferred_work_source_ = CFRunLoopSourceCreate(NULL, // allocator
389 0, // priority 165 0, // priority
390 &source_context); 166 &source_context);
391 CFRunLoopAddSourceToAllModes(run_loop_, nesting_deferred_work_source_); 167 CFRunLoopAddSourceToAllModes(run_loop_, nesting_deferred_work_source_);
392 168
393 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext(); 169 CFRunLoopObserverContext observer_context = CFRunLoopObserverContext();
394 observer_context.info = this; 170 observer_context.info = this;
395 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator 171 pre_wait_observer_ = CFRunLoopObserverCreate(NULL, // allocator
396 kCFRunLoopBeforeWaiting | 172 kCFRunLoopBeforeWaiting,
397 kCFRunLoopAfterWaiting,
398 true, // repeat 173 true, // repeat
399 0, // priority 174 0, // priority
400 StartOrEndWaitObserver, 175 PreWaitObserver,
401 &observer_context); 176 &observer_context);
402 CFRunLoopAddObserverToAllModes(run_loop_, pre_wait_observer_); 177 CFRunLoopAddObserverToAllModes(run_loop_, pre_wait_observer_);
403 178
404 pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator 179 pre_source_observer_ = CFRunLoopObserverCreate(NULL, // allocator
405 kCFRunLoopBeforeSources, 180 kCFRunLoopBeforeSources,
406 true, // repeat 181 true, // repeat
407 0, // priority 182 0, // priority
408 PreSourceObserver, 183 PreSourceObserver,
409 &observer_context); 184 &observer_context);
410 CFRunLoopAddObserverToAllModes(run_loop_, pre_source_observer_); 185 CFRunLoopAddObserverToAllModes(run_loop_, pre_source_observer_);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 CFRunLoopSourceSignal(work_source_); 250 CFRunLoopSourceSignal(work_source_);
476 delegateless_work_ = false; 251 delegateless_work_ = false;
477 } 252 }
478 if (delegateless_idle_work_) { 253 if (delegateless_idle_work_) {
479 CFRunLoopSourceSignal(idle_work_source_); 254 CFRunLoopSourceSignal(idle_work_source_);
480 delegateless_idle_work_ = false; 255 delegateless_idle_work_ = false;
481 } 256 }
482 } 257 }
483 } 258 }
484 259
485 void MessagePumpCFRunLoopBase::EnableInstrumentation() {
486 instrumentation_ = MessagePumpInstrumentation::Create(
487 TimeDelta::FromSeconds(1), TimeDelta::FromSeconds(15));
488 }
489
490 // May be called on any thread. 260 // May be called on any thread.
491 void MessagePumpCFRunLoopBase::ScheduleWork() { 261 void MessagePumpCFRunLoopBase::ScheduleWork() {
492 CFRunLoopSourceSignal(work_source_); 262 CFRunLoopSourceSignal(work_source_);
493 CFRunLoopWakeUp(run_loop_); 263 CFRunLoopWakeUp(run_loop_);
494 } 264 }
495 265
496 // Must be called on the run loop thread. 266 // Must be called on the run loop thread.
497 void MessagePumpCFRunLoopBase::ScheduleDelayedWork( 267 void MessagePumpCFRunLoopBase::ScheduleDelayedWork(
498 const TimeTicks& delayed_work_time) { 268 const TimeTicks& delayed_work_time) {
499 TimeDelta delta = delayed_work_time - TimeTicks::Now(); 269 TimeDelta delta = delayed_work_time - TimeTicks::Now();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 // Called by MessagePumpCFRunLoopBase::RunWorkSource. 306 // Called by MessagePumpCFRunLoopBase::RunWorkSource.
537 bool MessagePumpCFRunLoopBase::RunWork() { 307 bool MessagePumpCFRunLoopBase::RunWork() {
538 if (!delegate_) { 308 if (!delegate_) {
539 // This point can be reached with a NULL delegate_ if Run is not on the 309 // This point can be reached with a NULL delegate_ if Run is not on the
540 // stack but foreign code is spinning the CFRunLoop. Arrange to come back 310 // stack but foreign code is spinning the CFRunLoop. Arrange to come back
541 // here when a delegate is available. 311 // here when a delegate is available.
542 delegateless_work_ = true; 312 delegateless_work_ = true;
543 return false; 313 return false;
544 } 314 }
545 315
546 if (instrumentation_)
547 instrumentation_->WorkSourceEntered(delegate_);
548
549 // The NSApplication-based run loop only drains the autorelease pool at each 316 // The NSApplication-based run loop only drains the autorelease pool at each
550 // UI event (NSEvent). The autorelease pool is not drained for each 317 // UI event (NSEvent). The autorelease pool is not drained for each
551 // CFRunLoopSource target that's run. Use a local pool for any autoreleased 318 // CFRunLoopSource target that's run. Use a local pool for any autoreleased
552 // objects if the app is not currently handling a UI event to ensure they're 319 // objects if the app is not currently handling a UI event to ensure they're
553 // released promptly even in the absence of UI events. 320 // released promptly even in the absence of UI events.
554 MessagePumpScopedAutoreleasePool autorelease_pool(this); 321 MessagePumpScopedAutoreleasePool autorelease_pool(this);
555 322
556 // Call DoWork and DoDelayedWork once, and if something was done, arrange to 323 // Call DoWork and DoDelayedWork once, and if something was done, arrange to
557 // come back here again as long as the loop is still running. 324 // come back here again as long as the loop is still running.
558 bool did_work = delegate_->DoWork(); 325 bool did_work = delegate_->DoWork();
(...skipping 19 matching lines...) Expand all
578 // running. 345 // running.
579 resignal_work_source = true; 346 resignal_work_source = true;
580 } 347 }
581 } 348 }
582 } 349 }
583 350
584 if (resignal_work_source) { 351 if (resignal_work_source) {
585 CFRunLoopSourceSignal(work_source_); 352 CFRunLoopSourceSignal(work_source_);
586 } 353 }
587 354
588 if (instrumentation_)
589 instrumentation_->WorkSourceExited();
590
591 return resignal_work_source; 355 return resignal_work_source;
592 } 356 }
593 357
594 // Called from the run loop. 358 // Called from the run loop.
595 // static 359 // static
596 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) { 360 void MessagePumpCFRunLoopBase::RunIdleWorkSource(void* info) {
597 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 361 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
598 self->RunIdleWork(); 362 self->RunIdleWork();
599 } 363 }
600 364
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 // nesting-deferred work in case any work was deferred because nested work 429 // nesting-deferred work in case any work was deferred because nested work
666 // was disallowed. 430 // was disallowed.
667 if (deepest_nesting_level_ > nesting_level_) { 431 if (deepest_nesting_level_ > nesting_level_) {
668 deepest_nesting_level_ = nesting_level_; 432 deepest_nesting_level_ = nesting_level_;
669 CFRunLoopSourceSignal(nesting_deferred_work_source_); 433 CFRunLoopSourceSignal(nesting_deferred_work_source_);
670 } 434 }
671 } 435 }
672 436
673 // Called from the run loop. 437 // Called from the run loop.
674 // static 438 // static
675 void MessagePumpCFRunLoopBase::StartOrEndWaitObserver( 439 void MessagePumpCFRunLoopBase::PreWaitObserver(CFRunLoopObserverRef observer,
676 CFRunLoopObserverRef observer, 440 CFRunLoopActivity activity,
677 CFRunLoopActivity activity, 441 void* info) {
678 void* info) {
679 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 442 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
680 443
681 if (activity == kCFRunLoopAfterWaiting) {
682 if (self->instrumentation_)
683 self->instrumentation_->WaitingFinished();
684 return;
685 }
686
687 // Attempt to do some idle work before going to sleep. 444 // Attempt to do some idle work before going to sleep.
688 self->RunIdleWork(); 445 self->RunIdleWork();
689 446
690 // The run loop is about to go to sleep. If any of the work done since it 447 // The run loop is about to go to sleep. If any of the work done since it
691 // started or woke up resulted in a nested run loop running, 448 // started or woke up resulted in a nested run loop running,
692 // nesting-deferred work may have accumulated. Schedule it for processing 449 // nesting-deferred work may have accumulated. Schedule it for processing
693 // if appropriate. 450 // if appropriate.
694 self->MaybeScheduleNestingDeferredWork(); 451 self->MaybeScheduleNestingDeferredWork();
695
696 if (self->instrumentation_)
697 self->instrumentation_->WaitingStarted();
698 } 452 }
699 453
700 // Called from the run loop. 454 // Called from the run loop.
701 // static 455 // static
702 void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer, 456 void MessagePumpCFRunLoopBase::PreSourceObserver(CFRunLoopObserverRef observer,
703 CFRunLoopActivity activity, 457 CFRunLoopActivity activity,
704 void* info) { 458 void* info) {
705 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 459 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
706 460
707 // The run loop has reached the top of the loop and is about to begin 461 // The run loop has reached the top of the loop and is about to begin
708 // processing sources. If the last iteration of the loop at this nesting 462 // processing sources. If the last iteration of the loop at this nesting
709 // level did not sleep or exit, nesting-deferred work may have accumulated 463 // level did not sleep or exit, nesting-deferred work may have accumulated
710 // if a nested loop ran. Schedule nesting-deferred work for processing if 464 // if a nested loop ran. Schedule nesting-deferred work for processing if
711 // appropriate. 465 // appropriate.
712 self->MaybeScheduleNestingDeferredWork(); 466 self->MaybeScheduleNestingDeferredWork();
713 } 467 }
714 468
715 // Called from the run loop. 469 // Called from the run loop.
716 // static 470 // static
717 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer, 471 void MessagePumpCFRunLoopBase::EnterExitObserver(CFRunLoopObserverRef observer,
718 CFRunLoopActivity activity, 472 CFRunLoopActivity activity,
719 void* info) { 473 void* info) {
720 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info); 474 MessagePumpCFRunLoopBase* self = static_cast<MessagePumpCFRunLoopBase*>(info);
721 475
722 switch (activity) { 476 switch (activity) {
723 case kCFRunLoopEntry: 477 case kCFRunLoopEntry:
724 if (self->instrumentation_)
725 self->instrumentation_->LoopEntered();
726
727 ++self->nesting_level_; 478 ++self->nesting_level_;
728 if (self->nesting_level_ > self->deepest_nesting_level_) { 479 if (self->nesting_level_ > self->deepest_nesting_level_) {
729 self->deepest_nesting_level_ = self->nesting_level_; 480 self->deepest_nesting_level_ = self->nesting_level_;
730 } 481 }
731 break; 482 break;
732 483
733 case kCFRunLoopExit: 484 case kCFRunLoopExit:
734 // Not all run loops go to sleep. If a run loop is stopped before it 485 // Not all run loops go to sleep. If a run loop is stopped before it
735 // goes to sleep due to a CFRunLoopStop call, or if the timeout passed 486 // goes to sleep due to a CFRunLoopStop call, or if the timeout passed
736 // to CFRunLoopRunInMode expires, the run loop may proceed directly from 487 // to CFRunLoopRunInMode expires, the run loop may proceed directly from
737 // handling sources to exiting without any sleep. This most commonly 488 // handling sources to exiting without any sleep. This most commonly
738 // occurs when CFRunLoopRunInMode is passed a timeout of 0, causing it 489 // occurs when CFRunLoopRunInMode is passed a timeout of 0, causing it
739 // to make a single pass through the loop and exit without sleep. Some 490 // to make a single pass through the loop and exit without sleep. Some
740 // native loops use CFRunLoop in this way. Because StartOrEndWaitObserver 491 // native loops use CFRunLoop in this way. Because PreWaitObserver will
741 // will not be called in these case, MaybeScheduleNestingDeferredWork 492 // not be called in these case, MaybeScheduleNestingDeferredWork needs
742 // needs to be called here, as the run loop exits. 493 // to be called here, as the run loop exits.
743 // 494 //
744 // MaybeScheduleNestingDeferredWork consults self->nesting_level_ 495 // MaybeScheduleNestingDeferredWork consults self->nesting_level_
745 // to determine whether to schedule nesting-deferred work. It expects 496 // to determine whether to schedule nesting-deferred work. It expects
746 // the nesting level to be set to the depth of the loop that is going 497 // the nesting level to be set to the depth of the loop that is going
747 // to sleep or exiting. It must be called before decrementing the 498 // to sleep or exiting. It must be called before decrementing the
748 // value so that the value still corresponds to the level of the exiting 499 // value so that the value still corresponds to the level of the exiting
749 // loop. 500 // loop.
750 self->MaybeScheduleNestingDeferredWork(); 501 self->MaybeScheduleNestingDeferredWork();
751 --self->nesting_level_; 502 --self->nesting_level_;
752
753 if (self->instrumentation_)
754 self->instrumentation_->LoopExited();
755 break; 503 break;
756 504
757 default: 505 default:
758 break; 506 break;
759 } 507 }
760 508
761 self->EnterExitRunLoop(activity); 509 self->EnterExitRunLoop(activity);
762 } 510 }
763 511
764 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default 512 // Called by MessagePumpCFRunLoopBase::EnterExitRunLoop. The default
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 run_loop_ = new RunLoop(); 622 run_loop_ = new RunLoop();
875 CHECK(run_loop_->BeforeRun()); 623 CHECK(run_loop_->BeforeRun());
876 SetDelegate(delegate); 624 SetDelegate(delegate);
877 } 625 }
878 626
879 #else 627 #else
880 628
881 MessagePumpNSApplication::MessagePumpNSApplication() 629 MessagePumpNSApplication::MessagePumpNSApplication()
882 : keep_running_(true), 630 : keep_running_(true),
883 running_own_loop_(false) { 631 running_own_loop_(false) {
884 EnableInstrumentation();
885 } 632 }
886 633
887 MessagePumpNSApplication::~MessagePumpNSApplication() {} 634 MessagePumpNSApplication::~MessagePumpNSApplication() {}
888 635
889 void MessagePumpNSApplication::DoRun(Delegate* delegate) { 636 void MessagePumpNSApplication::DoRun(Delegate* delegate) {
890 if (instrumentation_)
891 instrumentation_->StartIfNeeded();
892
893 bool last_running_own_loop_ = running_own_loop_; 637 bool last_running_own_loop_ = running_own_loop_;
894 638
895 // NSApp must be initialized by calling: 639 // NSApp must be initialized by calling:
896 // [{some class which implements CrAppProtocol} sharedApplication] 640 // [{some class which implements CrAppProtocol} sharedApplication]
897 // Most likely candidates are CrApplication or BrowserCrApplication. 641 // Most likely candidates are CrApplication or BrowserCrApplication.
898 // These can be initialized from C++ code by calling 642 // These can be initialized from C++ code by calling
899 // RegisterCrApp() or RegisterBrowserCrApp(). 643 // RegisterCrApp() or RegisterBrowserCrApp().
900 CHECK(NSApp); 644 CHECK(NSApp);
901 645
902 if (![NSApp isRunning]) { 646 if (![NSApp isRunning]) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 [NSApplication sharedApplication]; 768 [NSApplication sharedApplication];
1025 g_not_using_cr_app = true; 769 g_not_using_cr_app = true;
1026 return new MessagePumpNSApplication; 770 return new MessagePumpNSApplication;
1027 #endif 771 #endif
1028 } 772 }
1029 773
1030 return new MessagePumpNSRunLoop; 774 return new MessagePumpNSRunLoop;
1031 } 775 }
1032 776
1033 } // namespace base 777 } // namespace base
OLDNEW
« no previous file with comments | « base/message_loop/message_pump_mac.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698