summaryrefslogtreecommitdiffstats
path: root/base/message_pump_mac.h
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-22 01:47:49 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-22 01:47:49 +0000
commit8670fe5e294c77abcd2d488bfaf06da7edf8e4bc (patch)
tree6a59432d7cc26980febba517355d67d8b3714e30 /base/message_pump_mac.h
parent8a425b86da0ee610854f00e0900326f34dfbd363 (diff)
downloadchromium_src-8670fe5e294c77abcd2d488bfaf06da7edf8e4bc.zip
chromium_src-8670fe5e294c77abcd2d488bfaf06da7edf8e4bc.tar.gz
chromium_src-8670fe5e294c77abcd2d488bfaf06da7edf8e4bc.tar.bz2
Change the strategy used to attempt nesting-deferred work to account equally
well for nested run loops under our own control (those started by Run) and those beyond our control (native event loops). Previously, upon any exit from a nested native loop, we would schedule nesting-deferred work for processing. However, some nested native loops do not execute in a single loop; rather, they start and stop the CFRunLoop rapidly. In such cases, each exit from the CFRunLoop would cause nesting-deferred work to be scheduled, and on each new entry to the CFRunLoop, we would attempt to process it. This rapid-fire action meant that we'd never sleep. Nested loops managed by Run were exempt from these problems since r28811, because we could defer scheduling nesting-deferred work until returning to Run. The new strategy is to detect whether any nested loops (native or managed by Run) had run before the run loop goes to sleep or exits. If any nested loops did run, nesting-deferred work is scheduled for processing. BUG=24968 TEST=1. Test case from bug 24968, printing: open any page, press command-P, leave the dialog up, and check Chrome's CPU usage. No Chrome process should be monopolizing any CPU. This tests nested native run loops. 2. Test case from bug 24337, JS alerts: open Gmail, start composing a new message in a new window, address it to yourself, move focus to the subject field, click the Discard button, and click "OK" at the alert. The alert and composition window should close. 3. Test case from bug 24383, JS alerts: no Chrome processes should use 100% CPU after visiting javascript:alert("hi"). The JS alert cases test nested run loops managed by Run. 4. Test case from bug 13468 comment 5, autocomplete: autocomplete should still work after using "Back" from a contextual menu. This tests that nesting-deferred work is processed after leaving a nested run loop. 5. First run UI test case (no bug). Remove or move aside the profile directory (~/Library/Application Support/Chromium or ~/Library/Application Support/Google/Chrome) and launch the application. There should be first-run UI and it should be usable. Upon clicking "Start (application)", the application should start and be usable as normal. This tests delegateless run loops and delegateless work redispatch. 6. base_unittests --gtest_filter='MessageLoopTest.*' Review URL: http://codereview.chromium.org/300044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29749 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_pump_mac.h')
-rw-r--r--base/message_pump_mac.h45
1 files changed, 30 insertions, 15 deletions
diff --git a/base/message_pump_mac.h b/base/message_pump_mac.h
index 34390c0..9c24d8b 100644
--- a/base/message_pump_mac.h
+++ b/base/message_pump_mac.h
@@ -54,17 +54,10 @@ class MessagePumpCFRunLoopBase : public MessagePump {
virtual void ScheduleDelayedWork(const Time& delayed_work_time);
protected:
- // The thread's run loop.
- CFRunLoopRef run_loop_;
-
- // The recursion depth of the currently-executing CFRunLoopRun loop on the
- // run loop's thread. 0 if no run loops are running inside of whatever scope
- // the object was created in.
- int nesting_level_;
-
- // The recursion depth (calculated in the same way as nesting_level_) of the
- // innermost executing CFRunLoopRun loop started by a call to Run.
- int run_nesting_level_;
+ // Accessors for private data members to be used by subclasses.
+ CFRunLoopRef run_loop() const { return run_loop_; }
+ int nesting_level() const { return nesting_level_; }
+ int run_nesting_level() const { return run_nesting_level_; }
private:
// Timer callback scheduled by ScheduleDelayedWork. This does not do any
@@ -96,13 +89,19 @@ class MessagePumpCFRunLoopBase : public MessagePump {
// Perform work that may have been deferred because it was not runnable
// within a nested run loop. This is associated with
- // nesting_deferred_work_source_ and is signalled by EnterExitObserver when
- // a run loop exits, so that an outer loop will be able to perform the
- // necessary tasks. The static method calls the instance method; the
- // instance method returns true if anything was done.
+ // nesting_deferred_work_source_ and is signalled by
+ // MaybeScheduleNestingDeferredWork when returning from a nested loop,
+ // so that an outer loop will be able to perform the necessary tasks if it
+ // permits nestable tasks.
static void RunNestingDeferredWorkSource(void* info);
bool RunNestingDeferredWork();
+ // Schedules possible nesting-deferred work to be processed before the run
+ // loop goes to sleep or exits. If this function detects that a nested loop
+ // had run since the previous attempt to schedule nesting-deferred work, it
+ // will schedule a call to RunNestingDeferredWorkSource.
+ void MaybeScheduleNestingDeferredWork();
+
// Observer callback responsible for performing idle-priority work, before
// the run loop goes to sleep. Associated with idle_work_observer_.
static void PreWaitObserver(CFRunLoopObserverRef observer,
@@ -119,6 +118,9 @@ class MessagePumpCFRunLoopBase : public MessagePump {
// the basis of run loops starting and stopping.
virtual void EnterExitRunLoop(CFRunLoopActivity activity);
+ // The thread's run loop.
+ CFRunLoopRef run_loop_;
+
// The timer, sources, and observers are described above alongside their
// callbacks.
CFRunLoopTimerRef delayed_work_timer_;
@@ -132,6 +134,19 @@ class MessagePumpCFRunLoopBase : public MessagePump {
// (weak) Delegate passed as an argument to the innermost Run call.
Delegate* delegate_;
+ // The recursion depth of the currently-executing CFRunLoopRun loop on the
+ // run loop's thread. 0 if no run loops are running inside of whatever scope
+ // the object was created in.
+ int nesting_level_;
+
+ // The recursion depth (calculated in the same way as nesting_level_) of the
+ // innermost executing CFRunLoopRun loop started by a call to Run.
+ int run_nesting_level_;
+
+ // The deepest (numerically highest) recursion depth encountered since the
+ // most recent attempt to run nesting-deferred work.
+ int deepest_nesting_level_;
+
// "Delegateless" work flags are set when work is ready to be performed but
// must wait until a delegate is available to process it. This can happen
// when a MessagePumpCFRunLoopBase is instantiated and work arrives without