summaryrefslogtreecommitdiffstats
path: root/ipc/mojo
diff options
context:
space:
mode:
authoramistry <amistry@chromium.org>2015-10-19 17:13:15 -0700
committerCommit bot <commit-bot@chromium.org>2015-10-20 00:14:04 +0000
commit55eeeffd666bd30f20bf596f117ea1a101d4b202 (patch)
treeba5a1d0a9cda05f80f5c82e9b8a98481c213ebf8 /ipc/mojo
parent45494de6b97a67849e80c6b4ab582ae1d86eac4c (diff)
downloadchromium_src-55eeeffd666bd30f20bf596f117ea1a101d4b202.zip
chromium_src-55eeeffd666bd30f20bf596f117ea1a101d4b202.tar.gz
chromium_src-55eeeffd666bd30f20bf596f117ea1a101d4b202.tar.bz2
Fold IPCSupportInitializer::ForceShutdown() with ShutDown().
A race is possible on browser shut down where the UI thread releases its last |ScopedIPCSupport| which then causes ShutDown() to call ForceShutdown() since the last reference is released. However, at the point ForceShutdown() is called, |lock_| is not held and so a utility process being created on the IO thead can call Init() and assume it has a reference to the IPC support. However, |shutting_down_| hasn't been set yet, so there's no way to cancel the shutdown process. This causes |ChannelManager| internally to post a task to the IO thread with a reference to itself, even though it is about to be destroyed. BUG=542069 Review URL: https://codereview.chromium.org/1412733006 Cr-Commit-Position: refs/heads/master@{#354924}
Diffstat (limited to 'ipc/mojo')
-rw-r--r--ipc/mojo/OWNERS4
-rw-r--r--ipc/mojo/scoped_ipc_support.cc31
2 files changed, 13 insertions, 22 deletions
diff --git a/ipc/mojo/OWNERS b/ipc/mojo/OWNERS
index 584a1f6..ae47a47 100644
--- a/ipc/mojo/OWNERS
+++ b/ipc/mojo/OWNERS
@@ -1,2 +1,4 @@
+amistry@chromium.org
morrita@chromium.org
-viettrungluu@chromium.org \ No newline at end of file
+rockot@chromium.org
+viettrungluu@chromium.org
diff --git a/ipc/mojo/scoped_ipc_support.cc b/ipc/mojo/scoped_ipc_support.cc
index 5729463..2465aa2 100644
--- a/ipc/mojo/scoped_ipc_support.cc
+++ b/ipc/mojo/scoped_ipc_support.cc
@@ -31,10 +31,7 @@ class IPCSupportInitializer : public mojo::embedder::ProcessDelegate {
~IPCSupportInitializer() override { DCHECK(!observer_); }
void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner);
- void ShutDown();
-
- // Forces the initializer to shut down even if scopers are still holding it.
- void ForceShutdown();
+ void ShutDown(bool force);
private:
// This watches for destruction of the MessageLoop that IPCSupportInitializer
@@ -52,7 +49,7 @@ class IPCSupportInitializer : public mojo::embedder::ProcessDelegate {
private:
// base::MessageLoop::DestructionObserver:
void WillDestroyCurrentMessageLoop() override {
- initializer_->ForceShutdown();
+ initializer_->ShutDown(true);
}
IPCSupportInitializer* initializer_;
@@ -112,24 +109,16 @@ void IPCSupportInitializer::Init(
}
}
-void IPCSupportInitializer::ShutDown() {
- {
- base::AutoLock locker(lock_);
- if (shutting_down_ || was_shut_down_)
- return;
- DCHECK(init_count_ > 0);
- if (init_count_ > 1) {
- init_count_--;
- return;
- }
- }
- ForceShutdown();
-}
-
-void IPCSupportInitializer::ForceShutdown() {
+void IPCSupportInitializer::ShutDown(bool force) {
base::AutoLock locker(lock_);
if (shutting_down_ || was_shut_down_)
return;
+ DCHECK(init_count_ > 0);
+ if (init_count_ > 1 && !force) {
+ init_count_--;
+ return;
+ }
+
shutting_down_ = true;
if (base::MessageLoop::current() &&
base::MessageLoop::current()->task_runner() == io_thread_task_runner_) {
@@ -173,7 +162,7 @@ ScopedIPCSupport::ScopedIPCSupport(
}
ScopedIPCSupport::~ScopedIPCSupport() {
- ipc_support_initializer.Get().ShutDown();
+ ipc_support_initializer.Get().ShutDown(false);
}
} // namespace IPC