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

Side by Side Diff: ipc/mojo/scoped_ipc_support.cc

Issue 1143433003: Force immediate Mojo EDK shutdown on IO loop destruction. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
12 #include "base/synchronization/condition_variable.h" 11 #include "base/synchronization/condition_variable.h"
13 #include "base/synchronization/lock.h" 12 #include "base/synchronization/lock.h"
14 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
15 #include "base/thread_task_runner_handle.h" 14 #include "base/thread_task_runner_handle.h"
16 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" 15 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
17 #include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h" 16 #include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h"
18 17
19 namespace IPC { 18 namespace IPC {
20 19
21 namespace { 20 namespace {
22 21
23 class IPCSupportInitializer : public mojo::embedder::ProcessDelegate { 22 class IPCSupportInitializer : public mojo::embedder::ProcessDelegate {
24 public: 23 public:
25 IPCSupportInitializer() 24 IPCSupportInitializer()
26 : init_count_(0), 25 : init_count_(0),
27 shutting_down_(false), 26 shutting_down_(false),
28 was_shut_down_(false), 27 was_shut_down_(false),
29 observer_(nullptr), 28 observer_(nullptr) {}
30 weak_factory_(this) {}
31 29
32 ~IPCSupportInitializer() override { DCHECK(!observer_); } 30 ~IPCSupportInitializer() override { DCHECK(!observer_); }
33 31
34 void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner); 32 void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner);
35 void ShutDown(); 33 void ShutDown();
36 34
37 // Forces the initializer to shut down even if scopers are still holding it. 35 // Forces the initializer to shut down even if scopers are still holding it.
38 void ForceShutdown(); 36 void ForceShutdown();
39 37
40 private: 38 private:
41 // This watches for destruction of the MessageLoop that IPCSupportInitializer 39 // This watches for destruction of the MessageLoop that IPCSupportInitializer
42 // uses for IO, and guarantees that the initializer is shut down if it still 40 // uses for IO, and guarantees that the initializer is shut down if it still
43 // exists when the loop is being destroyed. 41 // exists when the loop is being destroyed.
44 class MessageLoopObserver : public base::MessageLoop::DestructionObserver { 42 class MessageLoopObserver : public base::MessageLoop::DestructionObserver {
45 public: 43 public:
46 MessageLoopObserver( 44 MessageLoopObserver(IPCSupportInitializer* initializer)
47 scoped_refptr<base::TaskRunner> initializer_task_runner, 45 : initializer_(initializer) {}
48 base::WeakPtr<IPCSupportInitializer> weak_initializer)
49 : initializer_task_runner_(initializer_task_runner),
50 weak_initializer_(weak_initializer) {}
51 46
52 ~MessageLoopObserver() override { 47 ~MessageLoopObserver() override {
53 base::MessageLoop::current()->RemoveDestructionObserver(this); 48 base::MessageLoop::current()->RemoveDestructionObserver(this);
54 } 49 }
55 50
56 private: 51 private:
57 // base::MessageLoop::DestructionObserver: 52 // base::MessageLoop::DestructionObserver:
58 void WillDestroyCurrentMessageLoop() override { 53 void WillDestroyCurrentMessageLoop() override {
59 initializer_task_runner_->PostTask( 54 initializer_->ForceShutdown();
60 FROM_HERE,
61 base::Bind(&IPCSupportInitializer::ForceShutdown, weak_initializer_));
62 } 55 }
63 56
64 scoped_refptr<base::TaskRunner> initializer_task_runner_; 57 IPCSupportInitializer* initializer_;
65 base::WeakPtr<IPCSupportInitializer> weak_initializer_;
66 58
67 DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver); 59 DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver);
68 }; 60 };
69 61
70 void ShutDownOnIOThread(); 62 void ShutDownOnIOThread();
71 63
72 // mojo::embedder::ProcessDelegate: 64 // mojo::embedder::ProcessDelegate:
73 void OnShutdownComplete() override {} 65 void OnShutdownComplete() override {}
74 66
75 static void WatchMessageLoopOnIOThread(MessageLoopObserver* observer); 67 static void WatchMessageLoopOnIOThread(MessageLoopObserver* observer);
76 68
77 base::Lock lock_; 69 base::Lock lock_;
78 size_t init_count_; 70 size_t init_count_;
79 bool shutting_down_; 71 bool shutting_down_;
80 72
81 // This is used to track whether shutdown has occurred yet, since we can be 73 // This is used to track whether shutdown has occurred yet, since we can be
82 // shut down by either the scoper or IO MessageLoop destruction. 74 // shut down by either the scoper or IO MessageLoop destruction.
83 bool was_shut_down_; 75 bool was_shut_down_;
84 76
85 // The message loop destruction observer we have watching our IO loop. This 77 // The message loop destruction observer we have watching our IO loop. This
86 // is created on the initializer's own thread but is used and destroyed on the 78 // is created on the initializer's own thread but is used and destroyed on the
87 // IO thread. 79 // IO thread.
88 MessageLoopObserver* observer_; 80 MessageLoopObserver* observer_;
89 81
90 scoped_refptr<base::TaskRunner> io_thread_task_runner_; 82 scoped_refptr<base::TaskRunner> io_thread_task_runner_;
91 83
92 base::WeakPtrFactory<IPCSupportInitializer> weak_factory_;
93
94 DISALLOW_COPY_AND_ASSIGN(IPCSupportInitializer); 84 DISALLOW_COPY_AND_ASSIGN(IPCSupportInitializer);
95 }; 85 };
96 86
97 void IPCSupportInitializer::Init( 87 void IPCSupportInitializer::Init(
98 scoped_refptr<base::TaskRunner> io_thread_task_runner) { 88 scoped_refptr<base::TaskRunner> io_thread_task_runner) {
99 base::AutoLock locker(lock_); 89 base::AutoLock locker(lock_);
100 DCHECK((init_count_ == 0 && !io_thread_task_runner_) || 90 DCHECK((init_count_ == 0 && !io_thread_task_runner_) ||
101 io_thread_task_runner_ == io_thread_task_runner); 91 io_thread_task_runner_ == io_thread_task_runner);
102 92
103 if (shutting_down_) { 93 if (shutting_down_) {
104 // If reinitialized before a pending shutdown task is executed, we 94 // If reinitialized before a pending shutdown task is executed, we
105 // effectively cancel the shutdown task. 95 // effectively cancel the shutdown task.
106 DCHECK(init_count_ == 1); 96 DCHECK(init_count_ == 1);
107 shutting_down_ = false; 97 shutting_down_ = false;
108 return; 98 return;
109 } 99 }
110 100
111 init_count_++; 101 init_count_++;
112 if (init_count_ == 1) { 102 if (init_count_ == 1) {
113 was_shut_down_ = false; 103 was_shut_down_ = false;
114 observer_ = new MessageLoopObserver(base::ThreadTaskRunnerHandle::Get(), 104 observer_ = new MessageLoopObserver(this);
115 weak_factory_.GetWeakPtr());
116 io_thread_task_runner_ = io_thread_task_runner; 105 io_thread_task_runner_ = io_thread_task_runner;
117 io_thread_task_runner_->PostTask( 106 io_thread_task_runner_->PostTask(
118 FROM_HERE, base::Bind(&WatchMessageLoopOnIOThread, observer_)); 107 FROM_HERE, base::Bind(&WatchMessageLoopOnIOThread, observer_));
119 mojo::embedder::InitIPCSupport( 108 mojo::embedder::InitIPCSupport(
120 mojo::embedder::ProcessType::NONE, io_thread_task_runner_, this, 109 mojo::embedder::ProcessType::NONE, io_thread_task_runner_, this,
121 io_thread_task_runner_, mojo::embedder::ScopedPlatformHandle()); 110 io_thread_task_runner_, mojo::embedder::ScopedPlatformHandle());
122 } 111 }
123 } 112 }
124 113
125 void IPCSupportInitializer::ShutDown() { 114 void IPCSupportInitializer::ShutDown() {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 ScopedIPCSupport::ScopedIPCSupport( 169 ScopedIPCSupport::ScopedIPCSupport(
181 scoped_refptr<base::TaskRunner> io_thread_task_runner) { 170 scoped_refptr<base::TaskRunner> io_thread_task_runner) {
182 ipc_support_initializer.Get().Init(io_thread_task_runner); 171 ipc_support_initializer.Get().Init(io_thread_task_runner);
183 } 172 }
184 173
185 ScopedIPCSupport::~ScopedIPCSupport() { 174 ScopedIPCSupport::~ScopedIPCSupport() {
186 ipc_support_initializer.Get().ShutDown(); 175 ipc_support_initializer.Get().ShutDown();
187 } 176 }
188 177
189 } // namespace IPC 178 } // namespace IPC
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698