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

Side by Side Diff: third_party/mojo/src/mojo/edk/embedder/embedder.cc

Issue 954643002: Update mojo sdk to rev 3d23dae011859a2aae49f1d1adde705c8e85d819 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: use run_renderer_in_process() Created 5 years, 9 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "mojo/edk/embedder/embedder.h" 5 #include "mojo/edk/embedder/embedder.h"
6 6
7 #include "base/atomicops.h" 7 #include "base/atomicops.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
9 #include "base/location.h" 10 #include "base/location.h"
10 #include "base/logging.h" 11 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop_proxy.h" 13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/task_runner.h"
13 #include "mojo/edk/embedder/embedder_internal.h" 15 #include "mojo/edk/embedder/embedder_internal.h"
16 #include "mojo/edk/embedder/master_process_delegate.h"
14 #include "mojo/edk/embedder/platform_support.h" 17 #include "mojo/edk/embedder/platform_support.h"
18 #include "mojo/edk/embedder/process_delegate.h"
19 #include "mojo/edk/embedder/slave_process_delegate.h"
15 #include "mojo/edk/system/channel.h" 20 #include "mojo/edk/system/channel.h"
16 #include "mojo/edk/system/channel_manager.h" 21 #include "mojo/edk/system/channel_manager.h"
17 #include "mojo/edk/system/configuration.h" 22 #include "mojo/edk/system/configuration.h"
23 #include "mojo/edk/system/connection_manager.h"
18 #include "mojo/edk/system/core.h" 24 #include "mojo/edk/system/core.h"
25 #include "mojo/edk/system/master_connection_manager.h"
19 #include "mojo/edk/system/message_pipe_dispatcher.h" 26 #include "mojo/edk/system/message_pipe_dispatcher.h"
20 #include "mojo/edk/system/platform_handle_dispatcher.h" 27 #include "mojo/edk/system/platform_handle_dispatcher.h"
21 #include "mojo/edk/system/raw_channel.h" 28 #include "mojo/edk/system/raw_channel.h"
29 #include "mojo/edk/system/slave_connection_manager.h"
22 30
23 namespace mojo { 31 namespace mojo {
24 namespace embedder { 32 namespace embedder {
25 33
34 namespace internal {
35
36 // Declared in embedder_internal.h.
37 PlatformSupport* g_platform_support = nullptr;
38 system::Core* g_core = nullptr;
39 ProcessType g_process_type = ProcessType::UNINITIALIZED;
40
41 } // namespace internal
42
26 namespace { 43 namespace {
27 44
45 // The following global variables are set in |InitIPCSupport()| and reset by
46 // |ShutdownIPCSupport()|/|ShutdownIPCSupportOnIOThread()|.
47
48 // Note: This needs to be |AddRef()|ed/|Release()|d.
49 base::TaskRunner* g_delegate_thread_task_runner = nullptr;
50
51 ProcessDelegate* g_process_delegate = nullptr;
52
53 // Note: This needs to be |AddRef()|ed/|Release()|d.
54 base::TaskRunner* g_io_thread_task_runner = nullptr;
55
56 // Instance of |ConnectionManager| used by the channel manager (below).
57 system::ConnectionManager* g_connection_manager = nullptr;
58
59 // Instance of |ChannelManager| used by the channel management functions
60 // (|CreateChannel()|, etc.).
61 system::ChannelManager* g_channel_manager = nullptr;
62
28 // TODO(vtl): For now, we need this to be thread-safe (since theoretically we 63 // TODO(vtl): For now, we need this to be thread-safe (since theoretically we
29 // currently support multiple channel creation threads -- possibly one per 64 // currently support multiple channel creation threads -- possibly one per
30 // channel). Eventually, we won't need it to be thread-safe (we'll require a 65 // channel). Eventually, we won't need it to be thread-safe (we'll require a
31 // single I/O thread), and eventually we won't need it at all. Remember to 66 // single I/O thread), and eventually we won't need it at all. Remember to
32 // remove the base/atomicops.h include. 67 // remove the base/atomicops.h include.
33 system::ChannelId MakeChannelId() { 68 system::ChannelId MakeChannelId() {
34 // Note that |AtomicWord| is signed. 69 // Note that |AtomicWord| is signed.
35 static base::subtle::AtomicWord counter = 0; 70 static base::subtle::AtomicWord counter = 0;
36 71
37 base::subtle::AtomicWord new_counter_value = 72 base::subtle::AtomicWord new_counter_value =
38 base::subtle::NoBarrier_AtomicIncrement(&counter, 1); 73 base::subtle::NoBarrier_AtomicIncrement(&counter, 1);
39 // Don't allow the counter to wrap. Note that any (strictly) positive value is 74 // Don't allow the counter to wrap. Note that any (strictly) positive value is
40 // a valid |ChannelId| (and |NoBarrier_AtomicIncrement()| returns the value 75 // a valid |ChannelId| (and |NoBarrier_AtomicIncrement()| returns the value
41 // post-increment). 76 // post-increment).
42 CHECK_GT(new_counter_value, 0); 77 CHECK_GT(new_counter_value, 0);
43 // Use "negative" values for these IDs, so that we'll also be able to use 78 // Use "negative" values for these IDs, so that we'll also be able to use
44 // "positive" "process identifiers" (see connection_manager.h) as IDs (and 79 // "positive" "process identifiers" (see connection_manager.h) as IDs (and
45 // they won't conflict). 80 // they won't conflict).
46 return static_cast<system::ChannelId>(-new_counter_value); 81 return static_cast<system::ChannelId>(-new_counter_value);
47 } 82 }
48 83
84 // Note: Called on the I/O thread.
85 void ShutdownIPCSupportHelper() {
86 // Save these before nuking them using |ShutdownChannelOnIOThread()|.
87 scoped_refptr<base::TaskRunner> delegate_thread_task_runner(
88 g_delegate_thread_task_runner);
89 ProcessDelegate* process_delegate = g_process_delegate;
90
91 ShutdownIPCSupportOnIOThread();
92
93 bool ok = delegate_thread_task_runner->PostTask(
94 FROM_HERE, base::Bind(&ProcessDelegate::OnShutdownComplete,
95 base::Unretained(process_delegate)));
96 DCHECK(ok);
97 }
98
49 } // namespace 99 } // namespace
50 100
51 namespace internal {
52
53 // Declared in embedder_internal.h.
54 PlatformSupport* g_platform_support = nullptr;
55 system::Core* g_core = nullptr;
56 system::ChannelManager* g_channel_manager = nullptr;
57 MasterProcessDelegate* g_master_process_delegate = nullptr;
58 SlaveProcessDelegate* g_slave_process_delegate = nullptr;
59
60 } // namespace internal
61
62 Configuration* GetConfiguration() { 101 Configuration* GetConfiguration() {
63 return system::GetMutableConfiguration(); 102 return system::GetMutableConfiguration();
64 } 103 }
65 104
66 void Init(scoped_ptr<PlatformSupport> platform_support) { 105 void Init(scoped_ptr<PlatformSupport> platform_support) {
67 DCHECK(platform_support); 106 DCHECK(platform_support);
68 107
69 DCHECK(!internal::g_platform_support); 108 DCHECK(!internal::g_platform_support);
70 internal::g_platform_support = platform_support.release(); 109 internal::g_platform_support = platform_support.release();
71 110
72 DCHECK(!internal::g_core); 111 DCHECK(!internal::g_core);
73 internal::g_core = new system::Core(internal::g_platform_support); 112 internal::g_core = new system::Core(internal::g_platform_support);
74
75 DCHECK(!internal::g_channel_manager);
76 internal::g_channel_manager =
77 new system::ChannelManager(internal::g_platform_support);
78 } 113 }
79 114
80 void InitMaster(scoped_refptr<base::TaskRunner> delegate_thread_task_runner, 115 MojoResult AsyncWait(MojoHandle handle,
81 MasterProcessDelegate* master_process_delegate, 116 MojoHandleSignals signals,
82 scoped_refptr<base::TaskRunner> io_thread_task_runner) { 117 const base::Callback<void(MojoResult)>& callback) {
118 return internal::g_core->AsyncWait(handle, signals, callback);
119 }
120
121 MojoResult CreatePlatformHandleWrapper(
122 ScopedPlatformHandle platform_handle,
123 MojoHandle* platform_handle_wrapper_handle) {
124 DCHECK(platform_handle_wrapper_handle);
125
126 scoped_refptr<system::Dispatcher> dispatcher(
127 new system::PlatformHandleDispatcher(platform_handle.Pass()));
128
129 DCHECK(internal::g_core);
130 MojoHandle h = internal::g_core->AddDispatcher(dispatcher);
131 if (h == MOJO_HANDLE_INVALID) {
132 LOG(ERROR) << "Handle table full";
133 dispatcher->Close();
134 return MOJO_RESULT_RESOURCE_EXHAUSTED;
135 }
136
137 *platform_handle_wrapper_handle = h;
138 return MOJO_RESULT_OK;
139 }
140
141 MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
142 ScopedPlatformHandle* platform_handle) {
143 DCHECK(platform_handle);
144
145 DCHECK(internal::g_core);
146 scoped_refptr<system::Dispatcher> dispatcher(
147 internal::g_core->GetDispatcher(platform_handle_wrapper_handle));
148 if (!dispatcher)
149 return MOJO_RESULT_INVALID_ARGUMENT;
150
151 if (dispatcher->GetType() != system::Dispatcher::kTypePlatformHandle)
152 return MOJO_RESULT_INVALID_ARGUMENT;
153
154 *platform_handle =
155 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get())
156 ->PassPlatformHandle()
157 .Pass();
158 return MOJO_RESULT_OK;
159 }
160
161 void InitIPCSupport(ProcessType process_type,
162 scoped_refptr<base::TaskRunner> delegate_thread_task_runner,
163 ProcessDelegate* process_delegate,
164 scoped_refptr<base::TaskRunner> io_thread_task_runner,
165 ScopedPlatformHandle platform_handle) {
83 // |Init()| must have already been called. 166 // |Init()| must have already been called.
84 DCHECK(internal::g_core); 167 DCHECK(internal::g_core);
168 // And not |InitIPCSupport()| (without |ShutdownIPCSupport()|).
169 DCHECK(internal::g_process_type == ProcessType::UNINITIALIZED);
85 170
86 // TODO(vtl): This is temporary. We really want to construct a 171 internal::g_process_type = process_type;
87 // |MasterConnectionManager| here, which will in turn hold on to the delegate. 172
88 internal::g_master_process_delegate = master_process_delegate; 173 DCHECK(delegate_thread_task_runner);
174 DCHECK(!g_delegate_thread_task_runner);
175 g_delegate_thread_task_runner = delegate_thread_task_runner.get();
176 g_delegate_thread_task_runner->AddRef();
177
178 DCHECK(process_delegate->GetType() == process_type);
179 DCHECK(!g_process_delegate);
180 g_process_delegate = process_delegate;
181
182 DCHECK(io_thread_task_runner);
183 DCHECK(!g_io_thread_task_runner);
184 g_io_thread_task_runner = io_thread_task_runner.get();
185 g_io_thread_task_runner->AddRef();
186
187 DCHECK(!g_connection_manager);
188 switch (process_type) {
189 case ProcessType::UNINITIALIZED:
190 CHECK(false);
191 break;
192 case ProcessType::NONE:
193 DCHECK(!platform_handle.is_valid()); // We wouldn't do anything with it.
194 // Nothing to do.
195 break;
196 case ProcessType::MASTER:
197 DCHECK(!platform_handle.is_valid()); // We wouldn't do anything with it.
198 g_connection_manager = new system::MasterConnectionManager();
199 static_cast<system::MasterConnectionManager*>(g_connection_manager)
200 ->Init(g_delegate_thread_task_runner,
201 static_cast<MasterProcessDelegate*>(g_process_delegate));
202 break;
203 case ProcessType::SLAVE:
204 DCHECK(platform_handle.is_valid());
205 g_connection_manager = new system::SlaveConnectionManager();
206 static_cast<system::SlaveConnectionManager*>(g_connection_manager)
207 ->Init(g_delegate_thread_task_runner,
208 static_cast<SlaveProcessDelegate*>(g_process_delegate),
209 platform_handle.Pass());
210 break;
211 }
212
213 DCHECK(!g_channel_manager);
214 g_channel_manager =
215 new system::ChannelManager(internal::g_platform_support,
216 io_thread_task_runner, g_connection_manager);
89 } 217 }
90 218
91 void InitSlave(scoped_refptr<base::TaskRunner> delegate_thread_task_runner, 219 void ShutdownIPCSupportOnIOThread() {
92 SlaveProcessDelegate* slave_process_delegate, 220 DCHECK(internal::g_process_type != ProcessType::UNINITIALIZED);
93 scoped_refptr<base::TaskRunner> io_thread_task_runner,
94 ScopedPlatformHandle platform_handle) {
95 // |Init()| must have already been called.
96 DCHECK(internal::g_core);
97 221
98 // TODO(vtl): This is temporary. We really want to construct a 222 g_channel_manager->ShutdownOnIOThread();
99 // |SlaveConnectionManager| here, which will in turn hold on to the delegate. 223 delete g_channel_manager;
100 internal::g_slave_process_delegate = slave_process_delegate; 224 g_channel_manager = nullptr;
225
226 if (g_connection_manager) {
227 g_connection_manager->Shutdown();
228 delete g_connection_manager;
229 g_connection_manager = nullptr;
230 }
231
232 g_io_thread_task_runner->Release();
233 g_io_thread_task_runner = nullptr;
234
235 g_delegate_thread_task_runner->Release();
236 g_delegate_thread_task_runner = nullptr;
237
238 g_process_delegate = nullptr;
239
240 internal::g_process_type = ProcessType::UNINITIALIZED;
241 }
242
243 void ShutdownIPCSupport() {
244 DCHECK(internal::g_process_type != ProcessType::UNINITIALIZED);
245
246 bool ok = g_io_thread_task_runner->PostTask(
247 FROM_HERE, base::Bind(&ShutdownIPCSupportHelper));
248 DCHECK(ok);
249 }
250
251 void ConnectToSlave(SlaveInfo slave_info,
252 ScopedPlatformHandle platform_handle) {
253 DCHECK(platform_handle.is_valid());
254 DCHECK(internal::g_process_type == ProcessType::MASTER);
255 static_cast<system::MasterConnectionManager*>(g_connection_manager)
256 ->AddSlave(slave_info, platform_handle.Pass());
101 } 257 }
102 258
103 // TODO(vtl): Write tests for this. 259 // TODO(vtl): Write tests for this.
104 ScopedMessagePipeHandle CreateChannelOnIOThread( 260 ScopedMessagePipeHandle CreateChannelOnIOThread(
105 ScopedPlatformHandle platform_handle, 261 ScopedPlatformHandle platform_handle,
106 ChannelInfo** channel_info) { 262 ChannelInfo** channel_info) {
107 DCHECK(platform_handle.is_valid()); 263 DCHECK(platform_handle.is_valid());
108 DCHECK(channel_info); 264 DCHECK(channel_info);
109 265
110 *channel_info = new ChannelInfo(MakeChannelId()); 266 *channel_info = new ChannelInfo(MakeChannelId());
111 scoped_refptr<system::MessagePipeDispatcher> dispatcher = 267 scoped_refptr<system::MessagePipeDispatcher> dispatcher =
112 internal::g_channel_manager->CreateChannelOnIOThread( 268 g_channel_manager->CreateChannelOnIOThread((*channel_info)->channel_id,
113 (*channel_info)->channel_id, platform_handle.Pass()); 269 platform_handle.Pass());
114 270
115 ScopedMessagePipeHandle rv( 271 ScopedMessagePipeHandle rv(
116 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); 272 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher)));
117 CHECK(rv.is_valid()); 273 CHECK(rv.is_valid());
118 // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it 274 // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it
119 // once that's fixed. 275 // once that's fixed.
120 return rv.Pass(); 276 return rv.Pass();
121 } 277 }
122 278
123 ScopedMessagePipeHandle CreateChannel( 279 ScopedMessagePipeHandle CreateChannel(
124 ScopedPlatformHandle platform_handle, 280 ScopedPlatformHandle platform_handle,
125 scoped_refptr<base::TaskRunner> io_thread_task_runner, 281 scoped_refptr<base::TaskRunner> io_thread_task_runner,
126 DidCreateChannelCallback callback, 282 const DidCreateChannelCallback& callback,
127 scoped_refptr<base::TaskRunner> callback_thread_task_runner) { 283 scoped_refptr<base::TaskRunner> callback_thread_task_runner) {
128 DCHECK(platform_handle.is_valid()); 284 DCHECK(platform_handle.is_valid());
129 DCHECK(io_thread_task_runner); 285 DCHECK(io_thread_task_runner);
130 DCHECK(!callback.is_null()); 286 DCHECK(!callback.is_null());
131 287
132 system::ChannelId channel_id = MakeChannelId(); 288 system::ChannelId channel_id = MakeChannelId();
133 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo(channel_id)); 289 scoped_ptr<ChannelInfo> channel_info(new ChannelInfo(channel_id));
134 scoped_refptr<system::MessagePipeDispatcher> dispatcher = 290 scoped_refptr<system::MessagePipeDispatcher> dispatcher =
135 internal::g_channel_manager->CreateChannel( 291 g_channel_manager->CreateChannel(
136 channel_id, platform_handle.Pass(), io_thread_task_runner, 292 channel_id, platform_handle.Pass(), io_thread_task_runner,
137 base::Bind(callback, base::Unretained(channel_info.release())), 293 base::Bind(callback, base::Unretained(channel_info.release())),
138 callback_thread_task_runner); 294 callback_thread_task_runner);
139 295
140 ScopedMessagePipeHandle rv( 296 ScopedMessagePipeHandle rv(
141 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); 297 MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher)));
142 CHECK(rv.is_valid()); 298 CHECK(rv.is_valid());
143 // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it 299 // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it
144 // once that's fixed. 300 // once that's fixed.
145 return rv.Pass(); 301 return rv.Pass();
146 } 302 }
147 303
148 // TODO(vtl): Write tests for this. 304 // TODO(vtl): Write tests for this.
149 void DestroyChannel(ChannelInfo* channel_info) { 305 void DestroyChannelOnIOThread(ChannelInfo* channel_info) {
150 DCHECK(channel_info); 306 DCHECK(channel_info);
151 DCHECK(channel_info->channel_id); 307 DCHECK(channel_info->channel_id);
152 DCHECK(internal::g_channel_manager); 308 DCHECK(g_channel_manager);
153 // This will destroy the channel synchronously if called from the channel 309 g_channel_manager->ShutdownChannelOnIOThread(channel_info->channel_id);
154 // thread. 310 delete channel_info;
155 internal::g_channel_manager->ShutdownChannel(channel_info->channel_id); 311 }
312
313 // TODO(vtl): Write tests for this.
314 void DestroyChannel(
315 ChannelInfo* channel_info,
316 const DidDestroyChannelCallback& callback,
317 scoped_refptr<base::TaskRunner> callback_thread_task_runner) {
318 DCHECK(channel_info);
319 DCHECK(channel_info->channel_id);
320 DCHECK(!callback.is_null());
321 DCHECK(g_channel_manager);
322 g_channel_manager->ShutdownChannel(channel_info->channel_id, callback,
323 callback_thread_task_runner);
156 delete channel_info; 324 delete channel_info;
157 } 325 }
158 326
159 void WillDestroyChannelSoon(ChannelInfo* channel_info) { 327 void WillDestroyChannelSoon(ChannelInfo* channel_info) {
160 DCHECK(channel_info); 328 DCHECK(channel_info);
161 DCHECK(internal::g_channel_manager); 329 DCHECK(g_channel_manager);
162 internal::g_channel_manager->WillShutdownChannel(channel_info->channel_id); 330 g_channel_manager->WillShutdownChannel(channel_info->channel_id);
163 }
164
165 MojoResult CreatePlatformHandleWrapper(
166 ScopedPlatformHandle platform_handle,
167 MojoHandle* platform_handle_wrapper_handle) {
168 DCHECK(platform_handle_wrapper_handle);
169
170 scoped_refptr<system::Dispatcher> dispatcher(
171 new system::PlatformHandleDispatcher(platform_handle.Pass()));
172
173 DCHECK(internal::g_core);
174 MojoHandle h = internal::g_core->AddDispatcher(dispatcher);
175 if (h == MOJO_HANDLE_INVALID) {
176 LOG(ERROR) << "Handle table full";
177 dispatcher->Close();
178 return MOJO_RESULT_RESOURCE_EXHAUSTED;
179 }
180
181 *platform_handle_wrapper_handle = h;
182 return MOJO_RESULT_OK;
183 }
184
185 MojoResult PassWrappedPlatformHandle(MojoHandle platform_handle_wrapper_handle,
186 ScopedPlatformHandle* platform_handle) {
187 DCHECK(platform_handle);
188
189 DCHECK(internal::g_core);
190 scoped_refptr<system::Dispatcher> dispatcher(
191 internal::g_core->GetDispatcher(platform_handle_wrapper_handle));
192 if (!dispatcher)
193 return MOJO_RESULT_INVALID_ARGUMENT;
194
195 if (dispatcher->GetType() != system::Dispatcher::kTypePlatformHandle)
196 return MOJO_RESULT_INVALID_ARGUMENT;
197
198 *platform_handle =
199 static_cast<system::PlatformHandleDispatcher*>(dispatcher.get())
200 ->PassPlatformHandle()
201 .Pass();
202 return MOJO_RESULT_OK;
203 }
204
205 MojoResult AsyncWait(MojoHandle handle,
206 MojoHandleSignals signals,
207 base::Callback<void(MojoResult)> callback) {
208 return internal::g_core->AsyncWait(handle, signals, callback);
209 } 331 }
210 332
211 } // namespace embedder 333 } // namespace embedder
212 } // namespace mojo 334 } // namespace mojo
OLDNEW
« no previous file with comments | « third_party/mojo/src/mojo/edk/embedder/embedder.h ('k') | third_party/mojo/src/mojo/edk/embedder/embedder_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698