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 |