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

Unified Diff: base/message_loop.cc

Issue 10479018: Add base::RunLoop and update ui_test_utils to use it to reduce flakiness (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fetch/merge, no change Created 8 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « base/message_loop.h ('k') | base/message_loop_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/message_loop.cc
diff --git a/base/message_loop.cc b/base/message_loop.cc
index b040ecc8a6bf5f9bdde0d8229bfe493a5afd5a65..9f488e313ff8e7a637e4e99b377601c0d68c4cc1 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -131,7 +131,6 @@ MessageLoop::MessageLoop(Type type)
nestable_tasks_allowed_(true),
exception_restoration_(false),
message_histogram_(NULL),
- state_(NULL),
#ifdef OS_WIN
os_modal_loop_(false),
#endif // OS_WIN
@@ -180,7 +179,7 @@ MessageLoop::MessageLoop(Type type)
MessageLoop::~MessageLoop() {
DCHECK_EQ(this, current());
- DCHECK(!state_);
+ DCHECK(!run_loop_);
// Clean up any unprocessed tasks, but take care: deleting a task could
// result in the addition of more tasks (e.g., via DeleteSoon). We set a
@@ -292,21 +291,89 @@ void MessageLoop::PostNonNestableDelayedTask(
AddToIncomingQueue(&pending_task);
}
+MessageLoop::RunLoop::RunLoop()
+ : loop_(MessageLoop::current()),
+ run_called_(false),
+ stop_called_(false),
+ running_(false),
+ run_depth_(0),
+ quit_when_idle_received_(false) {
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
+ dispatcher_ = NULL;
+#endif
+}
+
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
+MessageLoop::RunLoop::RunLoop(Dispatcher* dispatcher)
+ : loop_(MessageLoop::current()),
+ run_called_(false),
+ stop_called_(false),
+ running_(false),
+ run_depth_(0),
+ quit_when_idle_received_(false),
+ dispatcher_(dispatcher) {
+}
+#endif
+
+MessageLoop::RunLoop::~RunLoop() {
+}
+
+void MessageLoop::RunLoop::Run() {
+ DCHECK(!run_called_);
+ run_called_ = true;
+
+ // Allow Stop to be called before Run (why not?).
+ if (stop_called_)
+ return;
+
+ // Push RunLoop stack:
+ base::WeakPtr<RunLoop> previous_run_loop = loop_->run_loop_;
+ run_depth_ = previous_run_loop? previous_run_loop->run_depth_ + 1 : 1;
+ loop_->run_loop_ = AsWeakPtr();
+
+ running_ = true;
+ loop_->RunHandler();
+ running_ = false;
+
+ // Pop RunLoop stack:
+ loop_->run_loop_ = previous_run_loop;
+
+ // Execute deferred QuitNow, if any:
+ if (previous_run_loop && previous_run_loop->stop_called_)
+ loop_->QuitNow();
+}
+
+void MessageLoop::RunLoop::RunUntilIdle() {
+ quit_when_idle_received_ = true;
+ Run();
+}
+
+void MessageLoop::RunLoop::Stop() {
+ stop_called_ = true;
+ if (running_ && loop_->run_loop_ == this) {
+ // This is the inner-most RunLoop, so quit now.
+ loop_->QuitNow();
+ }
+}
+
+base::Closure MessageLoop::RunLoop::StopClosure() {
+ return base::Bind(&RunLoop::Stop, AsWeakPtr());
+}
+
void MessageLoop::Run() {
- AutoRunState save_state(this);
- RunHandler();
+ RunLoop run_loop;
+ run_loop.Run();
}
void MessageLoop::RunAllPending() {
- AutoRunState save_state(this);
- state_->quit_received = true; // Means run until we would otherwise block.
- RunHandler();
+ RunLoop run_loop;
+ run_loop.RunUntilIdle();
}
-void MessageLoop::Quit() {
+void MessageLoop::QuitWhenIdle() {
DCHECK_EQ(this, current());
- if (state_) {
- state_->quit_received = true;
+ if (run_loop_) {
+ run_loop_->quit_when_idle_received_ = true;
} else {
NOTREACHED() << "Must be inside Run to call Quit";
}
@@ -314,20 +381,20 @@ void MessageLoop::Quit() {
void MessageLoop::QuitNow() {
DCHECK_EQ(this, current());
- if (state_) {
+ if (run_loop_) {
pump_->Quit();
} else {
NOTREACHED() << "Must be inside Run to call Quit";
}
}
-static void QuitCurrent() {
- MessageLoop::current()->Quit();
+static void QuitCurrentWhenIdle() {
+ MessageLoop::current()->QuitWhenIdle();
}
// static
-base::Closure MessageLoop::QuitClosure() {
- return base::Bind(&QuitCurrent);
+base::Closure MessageLoop::QuitWhenIdleClosure() {
+ return base::Bind(&QuitCurrentWhenIdle);
}
void MessageLoop::SetNestableTasksAllowed(bool allowed) {
@@ -345,7 +412,7 @@ bool MessageLoop::NestableTasksAllowed() const {
}
bool MessageLoop::IsNested() {
- return state_->run_depth > 1;
+ return run_loop_->run_depth_ > 1;
}
void MessageLoop::AddTaskObserver(TaskObserver* task_observer) {
@@ -366,7 +433,7 @@ void MessageLoop::AssertIdle() const {
bool MessageLoop::is_running() const {
DCHECK_EQ(this, current());
- return state_ != NULL;
+ return !!run_loop_;
}
//------------------------------------------------------------------------------
@@ -404,9 +471,9 @@ void MessageLoop::RunInternal() {
StartHistogrammer();
#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
- if (state_->dispatcher && type() == TYPE_UI) {
+ if (run_loop_->dispatcher_ && type() == TYPE_UI) {
static_cast<base::MessagePumpForUI*>(pump_.get())->
- RunWithDispatcher(this, state_->dispatcher);
+ RunWithDispatcher(this, run_loop_->dispatcher_);
return;
}
#endif
@@ -415,10 +482,10 @@ void MessageLoop::RunInternal() {
}
bool MessageLoop::ProcessNextDelayedNonNestableTask() {
- if (state_->run_depth != 1)
+ if (deferred_non_nestable_work_queue_.empty())
return false;
- if (deferred_non_nestable_work_queue_.empty())
+ if (run_loop_->run_depth_ != 1)
jbates 2012/06/22 02:12:51 Moved this down here, because it's cheaper to chec
return false;
PendingTask pending_task = deferred_non_nestable_work_queue_.front();
@@ -463,7 +530,7 @@ void MessageLoop::RunTask(const PendingTask& pending_task) {
}
bool MessageLoop::DeferOrRunPendingTask(const PendingTask& pending_task) {
- if (pending_task.nestable || state_->run_depth == 1) {
+ if (pending_task.nestable || run_loop_->run_depth_ == 1) {
RunTask(pending_task);
// Show that we ran a task (Note: a new one might arrive as a
// consequence!).
@@ -685,7 +752,7 @@ bool MessageLoop::DoIdleWork() {
if (ProcessNextDelayedNonNestableTask())
return true;
- if (state_->quit_received)
+ if (run_loop_->quit_when_idle_received_)
pump_->Quit();
return false;
@@ -705,30 +772,6 @@ void MessageLoop::ReleaseSoonInternal(
}
//------------------------------------------------------------------------------
-// MessageLoop::AutoRunState
-
-MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) {
- // Make the loop reference us.
- previous_state_ = loop_->state_;
- if (previous_state_) {
- run_depth = previous_state_->run_depth + 1;
- } else {
- run_depth = 1;
- }
- loop_->state_ = this;
-
- // Initialize the other fields:
- quit_received = false;
-#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
- dispatcher = NULL;
-#endif
-}
-
-MessageLoop::AutoRunState::~AutoRunState() {
- loop_->state_ = previous_state_;
-}
-
-//------------------------------------------------------------------------------
// MessageLoopForUI
#if defined(OS_WIN)
@@ -754,16 +797,13 @@ void MessageLoopForUI::RemoveObserver(Observer* observer) {
}
void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher) {
- AutoRunState save_state(this);
- state_->dispatcher = dispatcher;
- RunHandler();
+ RunLoop run_loop(dispatcher);
+ run_loop.Run();
}
void MessageLoopForUI::RunAllPendingWithDispatcher(Dispatcher* dispatcher) {
- AutoRunState save_state(this);
- state_->dispatcher = dispatcher;
- state_->quit_received = true; // Means run until we would otherwise block.
- RunHandler();
+ RunLoop run_loop(dispatcher);
+ run_loop.RunUntilIdle();
}
#endif // !defined(OS_MACOSX) && !defined(OS_NACL) && !defined(OS_ANDROID)
« no previous file with comments | « base/message_loop.h ('k') | base/message_loop_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698