Chromium Code Reviews| Index: base/message_loop.cc |
| diff --git a/base/message_loop.cc b/base/message_loop.cc |
| index a207659a4a922203a2e3850bbcdde4b1425dd21d..db3a3e6f388c3b7f052951641db6dd3f97194a10 100644 |
| --- a/base/message_loop.cc |
| +++ b/base/message_loop.cc |
| @@ -303,17 +303,25 @@ void MessageLoop::PostNonNestableDelayedTask( |
| } |
| void MessageLoop::Run() { |
| - AutoRunState save_state(this); |
| + AutoRunState save_state(this, NULL); |
| + RunHandler(); |
| +} |
| + |
| +void MessageLoop::RunWithID(const RunID& run_id) { |
| + DCHECK(run_id.get() && !run_id->used_); |
| + AutoRunState save_state(this, run_id); |
| + if (run_id->quit_now_received_) |
|
jar (doing other things)
2012/06/18 19:43:21
If you want to make the DCHECK in line 311 more va
jbates
2012/06/18 23:14:03
It's done by the AutoRunState constructor. I moved
|
| + return; |
| RunHandler(); |
| } |
| void MessageLoop::RunAllPending() { |
| - AutoRunState save_state(this); |
| + 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; |
| @@ -331,13 +339,51 @@ void MessageLoop::QuitNow() { |
| } |
| } |
| -static void QuitCurrent() { |
| - MessageLoop::current()->Quit(); |
| +void MessageLoop::QuitNowWithID(const RunID& run_id) { |
| + DCHECK_EQ(this, current()); |
| + 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(); |
| + |
| + // 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. |
|
jar (doing other things)
2012/06/18 19:43:21
Is the case of calling quit before the RunWithId()
jbates
2012/06/18 23:14:03
Explained in response to your other comment in mes
|
| + run_id->quit_now_received_ = true; |
| +} |
| + |
| +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::QuitNowClosure() { |
| + return base::Bind(&QuitCurrentNow); |
| } |
| // static |
| -base::Closure MessageLoop::QuitClosure() { |
| - return base::Bind(&QuitCurrent); |
| +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) { |
| @@ -716,9 +762,19 @@ 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_) { |
| @@ -728,6 +784,12 @@ MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) { |
| } |
| loop_->state_ = this; |
| + if (run_id.get()) { |
| + run_state_id = run_id; |
| + run_state_id->used_ = true; |
| + run_state_id->run_state_ = this; |
| + } |
| + |
| // Initialize the other fields: |
| quit_received = false; |
| #if !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| @@ -737,6 +799,13 @@ MessageLoop::AutoRunState::AutoRunState(MessageLoop* loop) : loop_(loop) { |
| 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,13 +834,20 @@ void MessageLoopForUI::RemoveObserver(Observer* observer) { |
| } |
| void MessageLoopForUI::RunWithDispatcher(Dispatcher* dispatcher) { |
| - AutoRunState save_state(this); |
| + 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); |
| + AutoRunState save_state(this, NULL); |
| state_->dispatcher = dispatcher; |
| state_->quit_received = true; // Means run until we would otherwise block. |
| RunHandler(); |