diff options
author | amistry <amistry@chromium.org> | 2015-10-19 17:13:15 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-20 00:14:04 +0000 |
commit | 55eeeffd666bd30f20bf596f117ea1a101d4b202 (patch) | |
tree | ba5a1d0a9cda05f80f5c82e9b8a98481c213ebf8 /ipc/mojo | |
parent | 45494de6b97a67849e80c6b4ab582ae1d86eac4c (diff) | |
download | chromium_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/OWNERS | 4 | ||||
-rw-r--r-- | ipc/mojo/scoped_ipc_support.cc | 31 |
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 |