| Index: base/message_loop.cc
|
| diff --git a/base/message_loop.cc b/base/message_loop.cc
|
| index b040ecc8a6bf5f9bdde0d8229bfe493a5afd5a65..0703631244a023c52716c9b3aba13f9792f12619 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,99 @@ 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() {
|
| + if (!BeforeRun())
|
| + return;
|
| + loop_->RunHandler();
|
| + AfterRun();
|
| +}
|
| +
|
| +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());
|
| +}
|
| +
|
| +bool MessageLoop::RunLoop::BeforeRun() {
|
| + DCHECK(!run_called_);
|
| + run_called_ = true;
|
| +
|
| + // Allow Stop to be called before Run.
|
| + if (stop_called_)
|
| + return false;
|
| +
|
| + // Push RunLoop stack:
|
| + previous_run_loop_ = loop_->run_loop_;
|
| + run_depth_ = previous_run_loop_? previous_run_loop_->run_depth_ + 1 : 1;
|
| + loop_->run_loop_ = AsWeakPtr();
|
| +
|
| + running_ = true;
|
| + return true;
|
| +}
|
| +
|
| +void MessageLoop::RunLoop::AfterRun() {
|
| + 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::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 +391,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 +422,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 +443,7 @@ void MessageLoop::AssertIdle() const {
|
|
|
| bool MessageLoop::is_running() const {
|
| DCHECK_EQ(this, current());
|
| - return state_ != NULL;
|
| + return !!run_loop_;
|
| }
|
|
|
| //------------------------------------------------------------------------------
|
| @@ -404,9 +481,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 +492,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)
|
| return false;
|
|
|
| PendingTask pending_task = deferred_non_nestable_work_queue_.front();
|
| @@ -463,7 +540,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 +762,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 +782,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 +807,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)
|
|
|