| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ipc/mojo/scoped_ipc_support.h" | 5 #include "ipc/mojo/scoped_ipc_support.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 public: | 24 public: |
| 25 IPCSupportInitializer() | 25 IPCSupportInitializer() |
| 26 : init_count_(0), | 26 : init_count_(0), |
| 27 shutting_down_(false), | 27 shutting_down_(false), |
| 28 was_shut_down_(false), | 28 was_shut_down_(false), |
| 29 observer_(nullptr) {} | 29 observer_(nullptr) {} |
| 30 | 30 |
| 31 ~IPCSupportInitializer() override { DCHECK(!observer_); } | 31 ~IPCSupportInitializer() override { DCHECK(!observer_); } |
| 32 | 32 |
| 33 void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner); | 33 void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner); |
| 34 void ShutDown(); | 34 void ShutDown(bool force); |
| 35 | |
| 36 // Forces the initializer to shut down even if scopers are still holding it. | |
| 37 void ForceShutdown(); | |
| 38 | 35 |
| 39 private: | 36 private: |
| 40 // This watches for destruction of the MessageLoop that IPCSupportInitializer | 37 // This watches for destruction of the MessageLoop that IPCSupportInitializer |
| 41 // uses for IO, and guarantees that the initializer is shut down if it still | 38 // uses for IO, and guarantees that the initializer is shut down if it still |
| 42 // exists when the loop is being destroyed. | 39 // exists when the loop is being destroyed. |
| 43 class MessageLoopObserver : public base::MessageLoop::DestructionObserver { | 40 class MessageLoopObserver : public base::MessageLoop::DestructionObserver { |
| 44 public: | 41 public: |
| 45 MessageLoopObserver(IPCSupportInitializer* initializer) | 42 MessageLoopObserver(IPCSupportInitializer* initializer) |
| 46 : initializer_(initializer) {} | 43 : initializer_(initializer) {} |
| 47 | 44 |
| 48 ~MessageLoopObserver() override { | 45 ~MessageLoopObserver() override { |
| 49 base::MessageLoop::current()->RemoveDestructionObserver(this); | 46 base::MessageLoop::current()->RemoveDestructionObserver(this); |
| 50 } | 47 } |
| 51 | 48 |
| 52 private: | 49 private: |
| 53 // base::MessageLoop::DestructionObserver: | 50 // base::MessageLoop::DestructionObserver: |
| 54 void WillDestroyCurrentMessageLoop() override { | 51 void WillDestroyCurrentMessageLoop() override { |
| 55 initializer_->ForceShutdown(); | 52 initializer_->ShutDown(true); |
| 56 } | 53 } |
| 57 | 54 |
| 58 IPCSupportInitializer* initializer_; | 55 IPCSupportInitializer* initializer_; |
| 59 | 56 |
| 60 DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver); | 57 DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver); |
| 61 }; | 58 }; |
| 62 | 59 |
| 63 void ShutDownOnIOThread(); | 60 void ShutDownOnIOThread(); |
| 64 | 61 |
| 65 // mojo::embedder::ProcessDelegate: | 62 // mojo::embedder::ProcessDelegate: |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 observer_ = new MessageLoopObserver(this); | 102 observer_ = new MessageLoopObserver(this); |
| 106 io_thread_task_runner_ = io_thread_task_runner; | 103 io_thread_task_runner_ = io_thread_task_runner; |
| 107 io_thread_task_runner_->PostTask( | 104 io_thread_task_runner_->PostTask( |
| 108 FROM_HERE, base::Bind(&WatchMessageLoopOnIOThread, observer_)); | 105 FROM_HERE, base::Bind(&WatchMessageLoopOnIOThread, observer_)); |
| 109 mojo::embedder::InitIPCSupport( | 106 mojo::embedder::InitIPCSupport( |
| 110 mojo::embedder::ProcessType::NONE, io_thread_task_runner_, this, | 107 mojo::embedder::ProcessType::NONE, io_thread_task_runner_, this, |
| 111 io_thread_task_runner_, mojo::embedder::ScopedPlatformHandle()); | 108 io_thread_task_runner_, mojo::embedder::ScopedPlatformHandle()); |
| 112 } | 109 } |
| 113 } | 110 } |
| 114 | 111 |
| 115 void IPCSupportInitializer::ShutDown() { | 112 void IPCSupportInitializer::ShutDown(bool force) { |
| 116 { | |
| 117 base::AutoLock locker(lock_); | |
| 118 if (shutting_down_ || was_shut_down_) | |
| 119 return; | |
| 120 DCHECK(init_count_ > 0); | |
| 121 if (init_count_ > 1) { | |
| 122 init_count_--; | |
| 123 return; | |
| 124 } | |
| 125 } | |
| 126 ForceShutdown(); | |
| 127 } | |
| 128 | |
| 129 void IPCSupportInitializer::ForceShutdown() { | |
| 130 base::AutoLock locker(lock_); | 113 base::AutoLock locker(lock_); |
| 131 if (shutting_down_ || was_shut_down_) | 114 if (shutting_down_ || was_shut_down_) |
| 132 return; | 115 return; |
| 116 DCHECK(init_count_ > 0); |
| 117 if (init_count_ > 1 && !force) { |
| 118 init_count_--; |
| 119 return; |
| 120 } |
| 121 |
| 133 shutting_down_ = true; | 122 shutting_down_ = true; |
| 134 if (base::MessageLoop::current() && | 123 if (base::MessageLoop::current() && |
| 135 base::MessageLoop::current()->task_runner() == io_thread_task_runner_) { | 124 base::MessageLoop::current()->task_runner() == io_thread_task_runner_) { |
| 136 base::AutoUnlock unlocker_(lock_); | 125 base::AutoUnlock unlocker_(lock_); |
| 137 ShutDownOnIOThread(); | 126 ShutDownOnIOThread(); |
| 138 } else { | 127 } else { |
| 139 io_thread_task_runner_->PostTask( | 128 io_thread_task_runner_->PostTask( |
| 140 FROM_HERE, base::Bind(&IPCSupportInitializer::ShutDownOnIOThread, | 129 FROM_HERE, base::Bind(&IPCSupportInitializer::ShutDownOnIOThread, |
| 141 base::Unretained(this))); | 130 base::Unretained(this))); |
| 142 } | 131 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 166 base::LazyInstance<IPCSupportInitializer>::Leaky ipc_support_initializer; | 155 base::LazyInstance<IPCSupportInitializer>::Leaky ipc_support_initializer; |
| 167 | 156 |
| 168 } // namespace | 157 } // namespace |
| 169 | 158 |
| 170 ScopedIPCSupport::ScopedIPCSupport( | 159 ScopedIPCSupport::ScopedIPCSupport( |
| 171 scoped_refptr<base::TaskRunner> io_thread_task_runner) { | 160 scoped_refptr<base::TaskRunner> io_thread_task_runner) { |
| 172 ipc_support_initializer.Get().Init(io_thread_task_runner); | 161 ipc_support_initializer.Get().Init(io_thread_task_runner); |
| 173 } | 162 } |
| 174 | 163 |
| 175 ScopedIPCSupport::~ScopedIPCSupport() { | 164 ScopedIPCSupport::~ScopedIPCSupport() { |
| 176 ipc_support_initializer.Get().ShutDown(); | 165 ipc_support_initializer.Get().ShutDown(false); |
| 177 } | 166 } |
| 178 | 167 |
| 179 } // namespace IPC | 168 } // namespace IPC |
| OLD | NEW |