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

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

Issue 1127293003: Update mojo sdk to rev f84766d3b6420b7cf6a113d9d65d73cb5fe18d90 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge IPC fixes 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
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"
10 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
11 #include "base/synchronization/condition_variable.h" 12 #include "base/synchronization/condition_variable.h"
12 #include "base/synchronization/lock.h" 13 #include "base/synchronization/lock.h"
13 #include "base/synchronization/waitable_event.h" 14 #include "base/synchronization/waitable_event.h"
14 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h" 15 #include "third_party/mojo/src/mojo/edk/embedder/embedder.h"
15 #include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h" 16 #include "third_party/mojo/src/mojo/edk/embedder/process_delegate.h"
16 17
17 namespace IPC { 18 namespace IPC {
18 19
19 namespace { 20 namespace {
20 21
21 class IPCSupportInitializer : public mojo::embedder::ProcessDelegate { 22 class IPCSupportInitializer : public mojo::embedder::ProcessDelegate {
22 public: 23 public:
23 IPCSupportInitializer() 24 IPCSupportInitializer()
24 : init_count_(0), 25 : init_count_(0),
25 shutting_down_(false) { 26 shutting_down_(false),
26 } 27 was_shut_down_(false),
28 observer_(nullptr),
29 weak_factory_(this) {}
27 30
28 ~IPCSupportInitializer() override {} 31 ~IPCSupportInitializer() override { DCHECK(!observer_); }
29 32
30 void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner) { 33 void Init(scoped_refptr<base::TaskRunner> io_thread_task_runner);
31 base::AutoLock locker(lock_); 34 void ShutDown();
32 DCHECK((init_count_ == 0 && !io_thread_task_runner_) ||
33 io_thread_task_runner_ == io_thread_task_runner);
34 35
35 if (shutting_down_) { 36 // Forces the initializer to shut down even if scopers are still holding it.
36 // If reinitialized before a pending shutdown task is executed, we 37 void ForceShutdown();
37 // effectively cancel the shutdown task. 38
38 DCHECK(init_count_ == 1); 39 private:
39 shutting_down_ = false; 40 // This watches for destruction of the MessageLoop that IPCSupportInitializer
40 return; 41 // uses for IO, and guarantees that the initializer is shut down if it still
42 // exists when the loop is being destroyed.
43 class MessageLoopObserver : public base::MessageLoop::DestructionObserver {
44 public:
45 MessageLoopObserver(base::WeakPtr<IPCSupportInitializer> weak_initializer)
46 : weak_initializer_(weak_initializer) {}
47
48 ~MessageLoopObserver() override {
49 base::MessageLoop::current()->RemoveDestructionObserver(this);
41 } 50 }
42 51
43 init_count_++; 52 private:
44 if (init_count_ == 1) { 53 // base::MessageLoop::DestructionObserver:
45 io_thread_task_runner_ = io_thread_task_runner; 54 void WillDestroyCurrentMessageLoop() override {
46 mojo::embedder::InitIPCSupport(mojo::embedder::ProcessType::NONE, 55 if (weak_initializer_)
47 io_thread_task_runner_, 56 weak_initializer_->ForceShutdown();
48 this, io_thread_task_runner_,
49 mojo::embedder::ScopedPlatformHandle());
50 }
51 }
52
53 void ShutDown() {
54 base::AutoLock locker(lock_);
55 DCHECK(init_count_ > 0);
56 DCHECK(!shutting_down_);
57
58 if (init_count_ > 1) {
59 init_count_--;
60 return;
61 } 57 }
62 58
63 shutting_down_ = true; 59 base::WeakPtr<IPCSupportInitializer> weak_initializer_;
64 if (base::MessageLoop::current() &&
65 base::MessageLoop::current()->task_runner() == io_thread_task_runner_) {
66 base::AutoUnlock unlocker_(lock_);
67 ShutDownOnIOThread();
68 } else {
69 io_thread_task_runner_->PostTask(
70 FROM_HERE,
71 base::Bind(&IPCSupportInitializer::ShutDownOnIOThread,
72 base::Unretained(this)));
73 }
74 }
75 60
76 private: 61 DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver);
77 void ShutDownOnIOThread() { 62 };
78 base::AutoLock locker(lock_);
79 if (shutting_down_) {
80 DCHECK(init_count_ == 1);
81 mojo::embedder::ShutdownIPCSupportOnIOThread();
82 init_count_ = 0;
83 shutting_down_ = false;
84 io_thread_task_runner_ = nullptr;
85 }
86 }
87 63
64 void ShutDownOnIOThread();
65
66 // mojo::embedder::ProcessDelegate:
88 void OnShutdownComplete() override {} 67 void OnShutdownComplete() override {}
89 68
69 static void WatchMessageLoopOnIOThread(MessageLoopObserver* observer);
70
90 base::Lock lock_; 71 base::Lock lock_;
91 size_t init_count_; 72 size_t init_count_;
92 bool shutting_down_; 73 bool shutting_down_;
93 74
75 // This is used to track whether shutdown has occurred yet, since we can be
76 // shut down by either the scoper or IO MessageLoop destruction.
77 bool was_shut_down_;
78
79 // The message loop destruction observer we have watching our IO loop. This
80 // is created on the initializer's own thread but is used and destroyed on the
81 // IO thread.
82 MessageLoopObserver* observer_;
83
94 scoped_refptr<base::TaskRunner> io_thread_task_runner_; 84 scoped_refptr<base::TaskRunner> io_thread_task_runner_;
95 85
86 base::WeakPtrFactory<IPCSupportInitializer> weak_factory_;
87
96 DISALLOW_COPY_AND_ASSIGN(IPCSupportInitializer); 88 DISALLOW_COPY_AND_ASSIGN(IPCSupportInitializer);
97 }; 89 };
98 90
91 void IPCSupportInitializer::Init(
92 scoped_refptr<base::TaskRunner> io_thread_task_runner) {
93 base::AutoLock locker(lock_);
94 DCHECK((init_count_ == 0 && !io_thread_task_runner_) ||
95 io_thread_task_runner_ == io_thread_task_runner);
96
97 if (shutting_down_) {
98 // If reinitialized before a pending shutdown task is executed, we
99 // effectively cancel the shutdown task.
100 DCHECK(init_count_ == 1);
101 shutting_down_ = false;
102 return;
103 }
104
105 init_count_++;
106 if (init_count_ == 1) {
107 was_shut_down_ = false;
108 observer_ = new MessageLoopObserver(weak_factory_.GetWeakPtr());
109 io_thread_task_runner_ = io_thread_task_runner;
110 io_thread_task_runner_->PostTask(
111 FROM_HERE, base::Bind(&WatchMessageLoopOnIOThread, observer_));
112 mojo::embedder::InitIPCSupport(
113 mojo::embedder::ProcessType::NONE, io_thread_task_runner_, this,
114 io_thread_task_runner_, mojo::embedder::ScopedPlatformHandle());
115 }
116 }
117
118 void IPCSupportInitializer::ShutDown() {
119 {
120 base::AutoLock locker(lock_);
121 DCHECK(init_count_ > 0);
122 if (init_count_ > 1) {
123 init_count_--;
124 return;
125 }
126 }
127 ForceShutdown();
128 }
129
130 void IPCSupportInitializer::ForceShutdown() {
131 base::AutoLock locker(lock_);
132 if (shutting_down_ || was_shut_down_)
133 return;
134 shutting_down_ = true;
135 if (base::MessageLoop::current() &&
136 base::MessageLoop::current()->task_runner() == io_thread_task_runner_) {
137 base::AutoUnlock unlocker_(lock_);
138 ShutDownOnIOThread();
139 } else {
140 io_thread_task_runner_->PostTask(
141 FROM_HERE, base::Bind(&IPCSupportInitializer::ShutDownOnIOThread,
142 base::Unretained(this)));
143 }
144 }
145
146 void IPCSupportInitializer::ShutDownOnIOThread() {
147 base::AutoLock locker(lock_);
148 if (shutting_down_ && !was_shut_down_) {
149 DCHECK(init_count_ == 1);
150 mojo::embedder::ShutdownIPCSupportOnIOThread();
151 init_count_ = 0;
152 shutting_down_ = false;
153 io_thread_task_runner_ = nullptr;
154 was_shut_down_ = true;
155 if (observer_) {
156 delete observer_;
157 observer_ = nullptr;
158 }
159 }
160 }
161
162 // static
163 void IPCSupportInitializer::WatchMessageLoopOnIOThread(
164 MessageLoopObserver* observer) {
165 base::MessageLoop::current()->AddDestructionObserver(observer);
166 }
167
99 base::LazyInstance<IPCSupportInitializer>::Leaky ipc_support_initializer; 168 base::LazyInstance<IPCSupportInitializer>::Leaky ipc_support_initializer;
100 169
101 } // namespace 170 } // namespace
102 171
103 ScopedIPCSupport::ScopedIPCSupport( 172 ScopedIPCSupport::ScopedIPCSupport(
104 scoped_refptr<base::TaskRunner> io_thread_task_runner) { 173 scoped_refptr<base::TaskRunner> io_thread_task_runner) {
105 ipc_support_initializer.Get().Init(io_thread_task_runner); 174 ipc_support_initializer.Get().Init(io_thread_task_runner);
106 } 175 }
107 176
108 ScopedIPCSupport::~ScopedIPCSupport() { 177 ScopedIPCSupport::~ScopedIPCSupport() {
109 ipc_support_initializer.Get().ShutDown(); 178 ipc_support_initializer.Get().ShutDown();
110 } 179 }
111 180
112 } // namespace IPC 181 } // namespace IPC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698