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

Unified Diff: ipc/mojo/async_handle_waiter.cc

Issue 973213002: Make AsyncHandleWaiter reenterancy-safe (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Landing Created 5 years, 10 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 | « ipc/mojo/async_handle_waiter.h ('k') | ipc/mojo/async_handle_waiter_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
« no previous file with comments | « ipc/mojo/async_handle_waiter.h ('k') | ipc/mojo/async_handle_waiter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698