| Index: ipc/mojo/async_handle_waiter.cc
|
| diff --git a/ipc/mojo/async_handle_waiter.cc b/ipc/mojo/async_handle_waiter.cc
|
| index 7b199ed95e835eec7dae4533ef4474f400030bf6..b9e68d7c4539886059b8428617eb43121eb19b4d 100644
|
| --- a/ipc/mojo/async_handle_waiter.cc
|
| +++ b/ipc/mojo/async_handle_waiter.cc
|
| @@ -9,7 +9,6 @@
|
| #include "base/bind_helpers.h"
|
| #include "base/location.h"
|
| #include "base/logging.h"
|
| -#include "base/message_loop/message_loop.h"
|
| #include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
|
|
|
| namespace IPC {
|
| @@ -32,7 +31,7 @@ class AsyncHandleWaiter::Context
|
| : io_runner_(base::MessageLoopForIO::current()->task_runner()),
|
| waiter_(waiter),
|
| last_result_(MOJO_RESULT_INTERNAL),
|
| - processing_(false),
|
| + io_loop_level_(0),
|
| should_invoke_callback_(false) {
|
| base::MessageLoopForIO::current()->AddIOObserver(this);
|
| }
|
| @@ -67,7 +66,7 @@ class AsyncHandleWaiter::Context
|
| return false;
|
| if (loop->task_runner() != io_runner_)
|
| return false;
|
| - return processing_;
|
| + return io_loop_level_ > 0;
|
| }
|
|
|
| // Called from |io_runner_| thus safe to touch |waiter_|.
|
| @@ -81,19 +80,25 @@ class AsyncHandleWaiter::Context
|
| // IOObserver implementation:
|
|
|
| void WillProcessIOEvent() override {
|
| - DCHECK(!should_invoke_callback_);
|
| - DCHECK(!processing_);
|
| - processing_ = true;
|
| + DCHECK(io_loop_level_ != 0 || !should_invoke_callback_);
|
| + DCHECK_GE(io_loop_level_, 0);
|
| + io_loop_level_++;
|
| }
|
|
|
| void DidProcessIOEvent() override {
|
| - DCHECK(processing_);
|
| + DCHECK_GE(io_loop_level_, 1);
|
| +
|
| + // Leaving a nested loop.
|
| + if (io_loop_level_ > 1) {
|
| + io_loop_level_--;
|
| + return;
|
| + }
|
|
|
| // The zero |waiter_| indicates that |this| have lost the owner and can be
|
| // under destruction. So we cannot wrap it with a |scoped_refptr| anymore.
|
| if (!waiter_) {
|
| should_invoke_callback_ = false;
|
| - processing_ = false;
|
| + io_loop_level_--;
|
| return;
|
| }
|
|
|
| @@ -105,7 +110,7 @@ class AsyncHandleWaiter::Context
|
| InvokeWaiterCallback();
|
| }
|
|
|
| - processing_ = false;
|
| + io_loop_level_--;
|
| }
|
|
|
| // Only |io_runner_| is accessed from arbitrary threads. Others are touched
|
| @@ -114,7 +119,7 @@ class AsyncHandleWaiter::Context
|
|
|
| const base::WeakPtr<AsyncHandleWaiter> waiter_;
|
| MojoResult last_result_;
|
| - bool processing_;
|
| + int io_loop_level_;
|
| bool should_invoke_callback_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(Context);
|
| @@ -139,6 +144,14 @@ void AsyncHandleWaiter::InvokeCallback(MojoResult result) {
|
| callback_.Run(result);
|
| }
|
|
|
| +base::MessageLoopForIO::IOObserver* AsyncHandleWaiter::GetIOObserverForTest() {
|
| + return context_.get();
|
| +}
|
| +
|
| +base::Callback<void(MojoResult)> AsyncHandleWaiter::GetWaitCallbackForTest() {
|
| + return base::Bind(&Context::HandleIsReady, context_);
|
| +}
|
| +
|
| // static
|
| void AsyncHandleWaiterContextTraits::Destruct(
|
| const AsyncHandleWaiter::Context* context) {
|
|
|