| Index: base/message_loop.cc
|
| diff --git a/base/message_loop.cc b/base/message_loop.cc
|
| index a207659a4a922203a2e3850bbcdde4b1425dd21d..e3f928699b77cef9a15d92a229eb3483c384e6fe 100644
|
| --- a/base/message_loop.cc
|
| +++ b/base/message_loop.cc
|
| @@ -303,20 +303,27 @@ void MessageLoop::PostNonNestableDelayedTask(
|
| }
|
|
|
| void MessageLoop::Run() {
|
| - AutoRunState save_state(this);
|
| + AutoRunState save_state(this, NULL);
|
| + RunHandler();
|
| +}
|
| +
|
| +void MessageLoop::RunWithID(const RunID& run_id) {
|
| + AutoRunState save_state(this, run_id);
|
| + if (run_id->quit_now_received_)
|
| + return;
|
| RunHandler();
|
| }
|
|
|
| void MessageLoop::RunAllPending() {
|
| - AutoRunState save_state(this);
|
| - state_->quit_received = true; // Means run until we would otherwise block.
|
| + AutoRunState save_state(this, NULL);
|
| + state_->quit_received_ = true; // Means run until we would otherwise block.
|
| RunHandler();
|
| }
|
|
|
| -void MessageLoop::Quit() {
|
| +void MessageLoop::QuitWhenIdle() {
|
| DCHECK_EQ(this, current());
|
| if (state_) {
|
| - state_->quit_received = true;
|
| + state_->quit_received_ = true;
|
| } else {
|
| NOTREACHED() << "Must be inside Run to call Quit";
|
| }
|
| @@ -331,13 +338,53 @@ void MessageLoop::QuitNow() {
|
| }
|
| }
|
|
|
| -static void QuitCurrent() {
|
| - MessageLoop::current()->Quit();
|
| +void MessageLoop::QuitNowWithID(const RunID& run_id) {
|
| + DCHECK_EQ(this, current());
|
| +
|
| + // Set quit_now_received_ so that the corresponding Run scope is quit as soon
|
| + // as it is returned to. It's also possible that the corresponding Run has not
|
| + // begun; in that case, this will cause the Run to immediately return.
|
| + run_id->quit_now_received_ = true;
|
| +
|
| + if (!state_)
|
| + return;
|
| +
|
| + // If the state_ pointer matches that of the RunIDObject, we're at the same
|
| + // Run scope, so quit now.
|
| + if (state_ == run_id->run_state_)
|
| + QuitNow();
|
| +}
|
| +
|
| +static void QuitCurrentWhenIdle() {
|
| + MessageLoop::current()->QuitWhenIdle();
|
| +}
|
| +
|
| +static void QuitCurrentNow() {
|
| + MessageLoop::current()->QuitNow();
|
| +}
|
| +
|
| +static void QuitCurrentNowWithID(const MessageLoop::RunID& run_id) {
|
| + MessageLoop::current()->QuitNowWithID(run_id);
|
| +}
|
| +
|
| +// static
|
| +base::Closure MessageLoop::QuitWhenIdleClosure() {
|
| + return base::Bind(&QuitCurrentWhenIdle);
|
| }
|
|
|
| // static
|
| -base::Closure MessageLoop::QuitClosure() {
|
| - return base::Bind(&QuitCurrent);
|
| +base::Closure MessageLoop::QuitNowClosure() {
|
| + return base::Bind(&QuitCurrentNow);
|
| +}
|
| +
|
| +// static
|
| +base::Closure MessageLoop::QuitNowWithIDClosure(
|
| + const RunID& run_id) {
|
| + return base::Bind(&QuitCurrentNowWithID, run_id);
|
| +}
|
| +
|
| +MessageLoop::RunID MessageLoop::GetRunID() {
|
| + return new RunIDObject();
|
| }
|
|
|
| void MessageLoop::SetNestableTasksAllowed(bool allowed) {
|
| @@ -355,7 +402,7 @@ bool MessageLoop::NestableTasksAllowed() const {
|
| }
|
|
|
| bool MessageLoop::IsNested() {
|
| - return state_->run_depth > 1;
|
| + return state_->run_depth_ > 1;
|
| }
|
|
|
| void MessageLoop::AddTaskObserver(TaskObserver* task_observer) {
|
| @@ -414,9 +461,9 @@ void MessageLoop::RunInternal() {
|
| StartHistogrammer();
|
|
|
| #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
|
| - if (state_->dispatcher && type() == TYPE_UI) {
|
| + if (state_->dispatcher_ && type() == TYPE_UI) {
|
| static_cast<base::MessagePumpForUI*>(pump_.get())->
|
| - RunWithDispatcher(this, state_->dispatcher);
|
| + RunWithDispatcher(this, state_->dispatcher_);
|
| return;
|
| }
|
| #endif
|
| @@ -425,7 +472,7 @@ void MessageLoop::RunInternal() {
|
| }
|
|
|
| bool MessageLoop::ProcessNextDelayedNonNestableTask() {
|
| - if (state_->run_depth != 1)
|
| + if (state_->run_depth_ != 1)
|
| return false;
|
|
|
| if (deferred_non_nestable_work_queue_.empty())
|
| @@ -473,7 +520,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 || state_->run_depth_ == 1) {
|
| RunTask(pending_task);
|
| // Show that we ran a task (Note: a new one might arrive as a
|
| // consequence!).
|
| @@ -696,7 +743,7 @@ bool MessageLoop::DoIdleWork() {
|
| if (ProcessNextDelayedNonNestableTask())
|
| return true;
|
|
|
| - if (state_->quit_received)
|
| + if (state_->quit_received_)
|
| pump_->Quit();
|
|
|
| return false;
|
| @@ -716,27 +763,51 @@ void MessageLoop::ReleaseSoonInternal(
|
| }
|
|
|
| //------------------------------------------------------------------------------
|
| +// MessageLoop::RunState
|
| +
|
| +MessageLoop::RunState::RunState() {
|
| +}
|
| +
|
| +MessageLoop::RunState::~RunState() {
|
| +}
|
| +
|
| +//------------------------------------------------------------------------------
|
| // MessageLoop::AutoRunState
|
|
|
| -MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) {
|
| +MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop, const RunID& run_id)
|
| + : loop_(loop) {
|
| // Make the loop reference us.
|
| previous_state_ = loop_->state_;
|
| if (previous_state_) {
|
| - run_depth = previous_state_->run_depth + 1;
|
| + run_depth_ = previous_state_->run_depth_ + 1;
|
| } else {
|
| - run_depth = 1;
|
| + run_depth_ = 1;
|
| }
|
| loop_->state_ = this;
|
|
|
| + if (run_id.get()) {
|
| + DCHECK(!run_id->used_);
|
| + run_state_id_ = run_id;
|
| + run_state_id_->used_ = true;
|
| + run_state_id_->run_state_ = this;
|
| + }
|
| +
|
| // Initialize the other fields:
|
| - quit_received = false;
|
| + quit_received_ = false;
|
| #if !defined(OS_MACOSX) && !defined(OS_ANDROID)
|
| - dispatcher = NULL;
|
| + dispatcher_ = NULL;
|
| #endif
|
| }
|
|
|
| MessageLoop::AutoRunState::~AutoRunState() {
|
| loop_->state_ = previous_state_;
|
| + if (run_state_id_.get()) {
|
| + // run_state_id_->run_state_ points to 'this', so clear it.
|
| + run_state_id_->run_state_ = NULL;
|
| + }
|
| + if (previous_state_ && previous_state_->run_state_id_.get()
|
| + && previous_state_->run_state_id_->quit_now_received_)
|
| + MessageLoop::current()->QuitNow();
|
| }
|
|
|
| //------------------------------------------------------------------------------
|
| @@ -765,15 +836,22 @@ void MessageLoopForUI::RemoveObserver(Observer* observer) {
|
| }
|
|
|
| void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher) {
|
| - AutoRunState save_state(this);
|
| - state_->dispatcher = dispatcher;
|
| + AutoRunState save_state(this, NULL);
|
| + state_->dispatcher_ = dispatcher;
|
| + RunHandler();
|
| +}
|
| +
|
| +void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher,
|
| + const RunID& run_id) {
|
| + AutoRunState save_state(this, run_id);
|
| + state_->dispatcher_ = dispatcher;
|
| RunHandler();
|
| }
|
|
|
| void MessageLoopForUI::RunAllPendingWithDispatcher(Dispatcher* dispatcher) {
|
| - AutoRunState save_state(this);
|
| - state_->dispatcher = dispatcher;
|
| - state_->quit_received = true; // Means run until we would otherwise block.
|
| + AutoRunState save_state(this, NULL);
|
| + state_->dispatcher_ = dispatcher;
|
| + state_->quit_received_ = true; // Means run until we would otherwise block.
|
| RunHandler();
|
| }
|
|
|
|
|