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

Side by Side Diff: ipc/ipc_mojo_bootstrap.cc

Issue 2136193003: Move ChannelMojo bindings to a custom multiplex router (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 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 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 "ipc/ipc_mojo_bootstrap.h" 5 #include "ipc/ipc_mojo_bootstrap.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8
9 #include <map>
10 #include <memory>
8 #include <utility> 11 #include <utility>
9 12
10 #include "base/callback.h" 13 #include "base/callback.h"
11 #include "base/logging.h" 14 #include "base/logging.h"
12 #include "base/macros.h" 15 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
14 #include "base/process/process_handle.h" 17 #include "base/process/process_handle.h"
18 #include "base/single_thread_task_runner.h"
19 #include "base/stl_util.h"
20 #include "base/synchronization/lock.h"
21 #include "base/threading/thread_task_runner_handle.h"
15 #include "build/build_config.h" 22 #include "build/build_config.h"
16 #include "ipc/ipc_message_utils.h" 23 #include "ipc/ipc_message_utils.h"
17 #include "ipc/ipc_platform_file.h" 24 #include "ipc/ipc_platform_file.h"
25 #include "mojo/public/cpp/bindings/associated_group.h"
26 #include "mojo/public/cpp/bindings/associated_group_controller.h"
18 #include "mojo/public/cpp/bindings/binding.h" 27 #include "mojo/public/cpp/bindings/binding.h"
28 #include "mojo/public/cpp/bindings/connector.h"
29 #include "mojo/public/cpp/bindings/interface_endpoint_client.h"
30 #include "mojo/public/cpp/bindings/interface_endpoint_controller.h"
31 #include "mojo/public/cpp/bindings/interface_id.h"
32 #include "mojo/public/cpp/bindings/message_header_validator.h"
33 #include "mojo/public/cpp/bindings/pipe_control_message_handler.h"
34 #include "mojo/public/cpp/bindings/pipe_control_message_handler_delegate.h"
35 #include "mojo/public/cpp/bindings/pipe_control_message_proxy.h"
19 36
20 namespace IPC { 37 namespace IPC {
21 38
22 namespace { 39 namespace {
23 40
41 class ChannelAssociatedGroupController
42 : public mojo::AssociatedGroupController,
43 public mojo::MessageReceiver,
44 public mojo::PipeControlMessageHandlerDelegate {
45 public:
46 ChannelAssociatedGroupController(bool for_proxy,
yzshen1 2016/07/13 16:46:45 nit: I feel that |for_proxy| may not be very accur
Ken Rockot(use gerrit already) 2016/07/13 17:36:24 done
47 mojo::ScopedMessagePipeHandle handle)
48 : mojo::AssociatedGroupController(base::ThreadTaskRunnerHandle::Get()),
49 task_runner_(base::ThreadTaskRunnerHandle::Get()),
50 id_namespace_mask_(for_proxy ? mojo::kInterfaceIdNamespaceMask : 0),
51 associated_group_(CreateAssociatedGroup()),
52 connector_(std::move(handle), mojo::Connector::SINGLE_THREADED_SEND,
53 base::ThreadTaskRunnerHandle::Get()),
54 header_validator_(
55 "IPC::mojom::Bootstrap [master] MessageHeaderValidator", this),
56 control_message_handler_(this),
57 control_message_proxy_(&connector_) {
58 connector_.set_incoming_receiver(&header_validator_);
59 connector_.set_connection_error_handler(
60 base::Bind(&ChannelAssociatedGroupController::OnPipeError,
61 base::Unretained(this)));
62 control_message_handler_.SetDescription(
63 "IPC::mojom::Bootstrap [master] PipeControlMessageHandler");
64 }
65
66 mojo::AssociatedGroup* associated_group() { return associated_group_.get(); }
67
68 void ShutDown() {
69 DCHECK(thread_checker_.CalledOnValidThread());
70 connector_.CloseMessagePipe();
71 OnPipeError();
72 associated_group_.reset();
73 }
74
75 void SetProxyTaskRunner(
76 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner) {
77 proxy_task_runner_ = proxy_task_runner;
78 }
79
80 // mojo::AssociatedGroupController:
81 void CreateEndpointHandlePair(
82 mojo::ScopedInterfaceEndpointHandle* local_endpoint,
83 mojo::ScopedInterfaceEndpointHandle* remote_endpoint) override {
84 base::AutoLock locker(lock_);
85 uint32_t id = 0;
86 do {
87 if (next_interface_id_ >= mojo::kInterfaceIdNamespaceMask)
88 next_interface_id_ = 1;
89 id = (next_interface_id_++) | id_namespace_mask_;
90 } while (ContainsKey(endpoints_, id));
91
92 Endpoint* endpoint = new Endpoint(this, id);
93 if (encountered_error_)
94 endpoint->set_peer_closed();
95 endpoints_.insert({ id, endpoint });
96
97 *local_endpoint = CreateScopedInterfaceEndpointHandle(id, true);
98 *remote_endpoint = CreateScopedInterfaceEndpointHandle(id, false);
99 }
100
101 mojo::ScopedInterfaceEndpointHandle CreateLocalEndpointHandle(
102 mojo::InterfaceId id) override {
103 if (!mojo::IsValidInterfaceId(id))
104 return mojo::ScopedInterfaceEndpointHandle();
105
106 base::AutoLock locker(lock_);
107 bool inserted = false;
108 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted);
109 if (inserted && encountered_error_)
110 endpoint->set_peer_closed();
111
112 return CreateScopedInterfaceEndpointHandle(id, true);
113 }
114
115 void CloseEndpointHandle(mojo::InterfaceId id, bool is_local) override {
116 if (!mojo::IsValidInterfaceId(id))
117 return;
118
119 base::AutoLock locker(lock_);
120 if (!is_local) {
121 DCHECK(ContainsKey(endpoints_, id));
122 DCHECK(!mojo::IsMasterInterfaceId(id));
123 control_message_proxy_.NotifyEndpointClosedBeforeSent(id);
124 return;
125 }
126
127 DCHECK(ContainsKey(endpoints_, id));
128 Endpoint* endpoint = endpoints_[id].get();
129 DCHECK(!endpoint->client());
130 DCHECK(!endpoint->closed());
131 MarkClosedAndMaybeRemove(endpoint);
132
133 if (!mojo::IsMasterInterfaceId(id))
134 control_message_proxy_.NotifyPeerEndpointClosed(id);
135 }
136
137 mojo::InterfaceEndpointController* AttachEndpointClient(
138 const mojo::ScopedInterfaceEndpointHandle& handle,
139 mojo::InterfaceEndpointClient* client,
140 scoped_refptr<base::SingleThreadTaskRunner> runner) override {
141 const mojo::InterfaceId id = handle.id();
142
143 DCHECK(mojo::IsValidInterfaceId(id));
144 DCHECK(client);
145
146 base::AutoLock locker(lock_);
147 DCHECK(ContainsKey(endpoints_, id));
148
149 Endpoint* endpoint = endpoints_[id].get();
150 endpoint->AttachClient(client, std::move(runner));
151
152 if (endpoint->peer_closed())
153 NotifyEndpointOfError(endpoint, true /* force_async */);
154
155 return endpoint;
156 }
157
158 void DetachEndpointClient(
159 const mojo::ScopedInterfaceEndpointHandle& handle) override {
160 const mojo::InterfaceId id = handle.id();
161
162 DCHECK(mojo::IsValidInterfaceId(id));
163
164 base::AutoLock locker(lock_);
165 DCHECK(ContainsKey(endpoints_, id));
166
167 Endpoint* endpoint = endpoints_[id].get();
168 endpoint->DetachClient();
169 }
170
171 void RaiseError() override {
172 if (task_runner_->BelongsToCurrentThread()) {
173 connector_.RaiseError();
174 } else {
175 task_runner_->PostTask(
176 FROM_HERE,
177 base::Bind(&ChannelAssociatedGroupController::RaiseError, this));
178 }
179 }
180
181 private:
182 class Endpoint;
183 friend class Endpoint;
184
185 class Endpoint : public base::RefCountedThreadSafe<Endpoint>,
186 public mojo::InterfaceEndpointController {
187 public:
188 Endpoint(ChannelAssociatedGroupController* controller, mojo::InterfaceId id)
189 : controller_(controller), id_(id) {}
190
191 mojo::InterfaceId id() const { return id_; }
192
193 bool closed() const {
194 controller_->lock_.AssertAcquired();
195 return closed_;
196 }
197
198 void set_closed() {
199 controller_->lock_.AssertAcquired();
200 closed_ = true;
201 }
202
203 bool peer_closed() const {
204 controller_->lock_.AssertAcquired();
205 return peer_closed_;
206 }
207
208 void set_peer_closed() {
209 controller_->lock_.AssertAcquired();
210 peer_closed_ = true;
211 }
212
213 base::SingleThreadTaskRunner* task_runner() const {
214 return task_runner_.get();
215 }
216
217 mojo::InterfaceEndpointClient* client() const {
218 controller_->lock_.AssertAcquired();
219 return client_;
220 }
221
222 void AttachClient(mojo::InterfaceEndpointClient* client,
223 scoped_refptr<base::SingleThreadTaskRunner> runner) {
224 controller_->lock_.AssertAcquired();
225 DCHECK(!client_);
226 DCHECK(!closed_);
227 DCHECK(runner->BelongsToCurrentThread());
228
229 task_runner_ = std::move(runner);
230 client_ = client;
231 }
232
233 void DetachClient() {
234 controller_->lock_.AssertAcquired();
235 DCHECK(client_);
236 DCHECK(task_runner_->BelongsToCurrentThread());
237 DCHECK(!closed_);
238
239 task_runner_ = nullptr;
240 client_ = nullptr;
241 }
242
243 // mojo::InterfaceEndpointController:
244 bool SendMessage(mojo::Message* message) override {
245 DCHECK(task_runner_->BelongsToCurrentThread());
246 message->set_interface_id(id_);
247 return controller_->SendMessage(message);
248 }
249
250 void AllowWokenUpBySyncWatchOnSameThread() override {
251 DCHECK(task_runner_->BelongsToCurrentThread());
252
253 // It's not legal to make sync calls from the master endpoint's thread,
254 // and in fact they must only happen from the proxy task runner.
255 DCHECK(!controller_->task_runner_->BelongsToCurrentThread());
256 DCHECK(controller_->proxy_task_runner_->BelongsToCurrentThread());
257
258 // TODO(rockot): Implement sync waiting.
259 NOTREACHED();
260 }
261
262 bool SyncWatch(const bool* should_stop) override {
263 DCHECK(task_runner_->BelongsToCurrentThread());
264
265 // It's not legal to make sync calls from the master endpoint's thread,
266 // and in fact they must only happen from the proxy task runner.
267 DCHECK(!controller_->task_runner_->BelongsToCurrentThread());
268 DCHECK(controller_->proxy_task_runner_->BelongsToCurrentThread());
269
270 // TODO(rockot): Implement sync waiting.
271 NOTREACHED();
272 return false;
273 }
274
275 private:
276 friend class base::RefCountedThreadSafe<Endpoint>;
277
278 ~Endpoint() override {}
279
280 ChannelAssociatedGroupController* const controller_;
281 const mojo::InterfaceId id_;
282
283 bool closed_ = false;
284 bool peer_closed_ = false;
285 mojo::InterfaceEndpointClient* client_ = nullptr;
286 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
287
288 DISALLOW_COPY_AND_ASSIGN(Endpoint);
289 };
290
291 ~ChannelAssociatedGroupController() override {}
292
293 bool SendMessage(mojo::Message* message) {
294 if (task_runner_->BelongsToCurrentThread()) {
295 DCHECK(thread_checker_.CalledOnValidThread());
296 return connector_.Accept(message);
297 } else {
298 // We always post tasks to the master endpoint thread when called from the
299 // proxy thread in order to simulate IPC::ChannelProxy::Send behavior.
300 DCHECK(proxy_task_runner_ &&
301 proxy_task_runner_->BelongsToCurrentThread());
302 std::unique_ptr<mojo::Message> passed_message(new mojo::Message);
303 message->MoveTo(passed_message.get());
304 task_runner_->PostTask(
305 FROM_HERE,
306 base::Bind(
307 &ChannelAssociatedGroupController::SendMessageOnMasterThread,
308 this, base::Passed(&passed_message)));
309 return true;
310 }
311 }
312
313 void SendMessageOnMasterThread(std::unique_ptr<mojo::Message> message) {
314 DCHECK(thread_checker_.CalledOnValidThread());
315 if (!SendMessage(message.get()))
316 RaiseError();
317 }
318
319 void OnPipeError() {
320 DCHECK(thread_checker_.CalledOnValidThread());
321
322 base::AutoLock locker(lock_);
323 encountered_error_ = true;
324
325 std::vector<scoped_refptr<Endpoint>> endpoints_to_notify;
326 for (auto iter = endpoints_.begin(); iter != endpoints_.end();) {
327 Endpoint* endpoint = iter->second.get();
328 ++iter;
329
330 if (endpoint->client())
331 endpoints_to_notify.push_back(endpoint);
332
333 MarkPeerClosedAndMaybeRemove(endpoint);
334 }
335
336 // We keep |this| alive here because it's possible for the notifications
337 // below to release all other references.
338 scoped_refptr<ChannelAssociatedGroupController> keepalive(this);
339 for (auto& endpoint : endpoints_to_notify) {
340 // Because an notification may in turn detach any endpoint, we have to
341 // check each client again here.
342 if (endpoint->client())
343 NotifyEndpointOfError(endpoint.get(), false /* force_async */);
344 }
345 }
346
347 void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) {
348 lock_.AssertAcquired();
349 DCHECK(endpoint->task_runner() && endpoint->client());
350 if (endpoint->task_runner()->BelongsToCurrentThread() && !force_async) {
351 mojo::InterfaceEndpointClient* client = endpoint->client();
352
353 base::AutoUnlock unlocker(lock_);
354 client->NotifyError();
355 } else {
356 endpoint->task_runner()->PostTask(
357 FROM_HERE,
358 base::Bind(&ChannelAssociatedGroupController
359 ::NotifyEndpointOfErrorOnEndpointThread, this,
360 make_scoped_refptr(endpoint)));
361 }
362 }
363
364 void NotifyEndpointOfErrorOnEndpointThread(scoped_refptr<Endpoint> endpoint) {
365 base::AutoLock locker(lock_);
366 if (!endpoint->client())
367 return;
368 DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
369 NotifyEndpointOfError(endpoint.get(), false /* force_async */);
370 }
371
372 bool MarkClosedAndMaybeRemove(Endpoint* endpoint) {
yzshen1 2016/07/13 16:46:45 The return value is never used.
Ken Rockot(use gerrit already) 2016/07/13 17:36:24 Oops, they were used at one point. Removed :)
373 lock_.AssertAcquired();
374 endpoint->set_closed();
375 if (endpoint->closed() && endpoint->peer_closed()) {
376 endpoints_.erase(endpoint->id());
377 return true;
378 }
379 return false;
380 }
381
382 bool MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) {
yzshen1 2016/07/13 16:46:45 ditto.
Ken Rockot(use gerrit already) 2016/07/13 17:36:24 done
383 lock_.AssertAcquired();
384 endpoint->set_peer_closed();
385 if (endpoint->closed() && endpoint->peer_closed()) {
386 endpoints_.erase(endpoint->id());
387 return true;
388 }
389 return false;
390 }
391
392 Endpoint* FindOrInsertEndpoint(mojo::InterfaceId id, bool* inserted) {
393 lock_.AssertAcquired();
394 DCHECK(!inserted || !*inserted);
395
396 auto iter = endpoints_.find(id);
397 if (iter != endpoints_.end())
398 return iter->second.get();
399
400 Endpoint* endpoint = new Endpoint(this, id);
401 endpoints_.insert({ id, endpoint });
402 if (inserted)
403 *inserted = true;
404 return endpoint;
405 }
406
407 // mojo::MessageReceiver:
408 bool Accept(mojo::Message* message) override {
409 DCHECK(thread_checker_.CalledOnValidThread());
410
411 if (mojo::PipeControlMessageHandler::IsPipeControlMessage(message)) {
412 if (!control_message_handler_.Accept(message))
413 RaiseError();
414 return true;
415 }
416
417 mojo::InterfaceId id = message->interface_id();
418 DCHECK(mojo::IsValidInterfaceId(id));
419
420 base::AutoLock locker(lock_);
421 bool inserted = false;
422 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted);
423 if (inserted) {
424 MarkClosedAndMaybeRemove(endpoint);
425 if (!mojo::IsMasterInterfaceId(id))
426 control_message_proxy_.NotifyPeerEndpointClosed(id);
427 return true;
428 }
429
430 if (endpoint->closed())
431 return true;
432
433 mojo::InterfaceEndpointClient* client = endpoint->client();
434 if (!client || !endpoint->task_runner()->BelongsToCurrentThread()) {
435 // No client has been bound yet or the client runs tasks on another
436 // thread. We assume the other thread must always be the one on which
437 // |proxy_task_runner_| runs tasks, since that's the only valid scenario.
438 //
439 // If the client is not yet bound, it must be bound by the time this task
440 // runs or else it's programmer error.
441 DCHECK(proxy_task_runner_);
442 CHECK(false);
yzshen1 2016/07/13 16:46:45 Remove this CHECK?
Ken Rockot(use gerrit already) 2016/07/13 17:36:24 Done
443 std::unique_ptr<mojo::Message> passed_message(new mojo::Message);
444 message->MoveTo(passed_message.get());
445 proxy_task_runner_->PostTask(
446 FROM_HERE,
447 base::Bind(&ChannelAssociatedGroupController::AcceptOnProxyThread,
448 this, base::Passed(&passed_message)));
449 return true;
450 }
451
452 // We do not expect to receive sync responses on the master endpoint thread.
453 // If it's happening, it's a bug.
454 DCHECK(!message->has_flag(mojo::Message::kFlagIsSync));
455
456 bool result = false;
457 {
458 base::AutoUnlock unlocker(lock_);
459 result = client->HandleIncomingMessage(message);
460 }
461
462 if (!result)
463 RaiseError();
464
465 return true;
466 }
467
468 void AcceptOnProxyThread(std::unique_ptr<mojo::Message> message) {
469 DCHECK(proxy_task_runner_->BelongsToCurrentThread());
470
471 // TODO(rockot): Implement this.
472 NOTREACHED();
473 }
474
475 // mojo::PipeControlMessageHandlerDelegate:
476 bool OnPeerAssociatedEndpointClosed(mojo::InterfaceId id) override {
477 DCHECK(thread_checker_.CalledOnValidThread());
478
479 if (mojo::IsMasterInterfaceId(id))
480 return false;
481
482 base::AutoLock locker(lock_);
483 Endpoint* endpoint = FindOrInsertEndpoint(id, nullptr);
484 if (!endpoint->peer_closed()) {
485 if (endpoint->client())
486 NotifyEndpointOfError(endpoint, false /* force_async */);
487 MarkPeerClosedAndMaybeRemove(endpoint);
488 }
489
490 return true;
491 }
492
493 bool OnAssociatedEndpointClosedBeforeSent(mojo::InterfaceId id) override {
494 DCHECK(thread_checker_.CalledOnValidThread());
495
496 if (mojo::IsMasterInterfaceId(id))
497 return false;
498
499 Endpoint* endpoint = FindOrInsertEndpoint(id, nullptr);
yzshen1 2016/07/13 16:46:45 Is a locker missing here?
Ken Rockot(use gerrit already) 2016/07/13 17:36:24 Yes! Thanks, fixed
500 DCHECK(!endpoint->closed());
501 MarkClosedAndMaybeRemove(endpoint);
502 control_message_proxy_.NotifyPeerEndpointClosed(id);
503 return true;
504 }
505
506 // Checked in places which must be run on the master endpoint's thread.
507 base::ThreadChecker thread_checker_;
508
509 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
510 scoped_refptr<base::SingleThreadTaskRunner> proxy_task_runner_;
511 const uint32_t id_namespace_mask_;
512 std::unique_ptr<mojo::AssociatedGroup> associated_group_;
513 mojo::Connector connector_;
514 mojo::MessageHeaderValidator header_validator_;
515 mojo::PipeControlMessageHandler control_message_handler_;
516
517 // Guards the fields below for thread-safe access.
518 base::Lock lock_;
519
520 bool encountered_error_ = false;
521 uint32_t next_interface_id_ = 1;
522 std::map<uint32_t, scoped_refptr<Endpoint>> endpoints_;
523 mojo::PipeControlMessageProxy control_message_proxy_;
524
525 DISALLOW_COPY_AND_ASSIGN(ChannelAssociatedGroupController);
526 };
527
528 class BootstrapMasterProxy {
529 public:
530 BootstrapMasterProxy() {}
531 ~BootstrapMasterProxy() {
532 endpoint_client_.reset();
533 proxy_.reset();
534 if (controller_)
535 controller_->ShutDown();
536 }
537
538 void Bind(mojo::ScopedMessagePipeHandle handle) {
539 DCHECK(!controller_);
540 controller_ = new ChannelAssociatedGroupController(true, std::move(handle));
541 endpoint_client_.reset(new mojo::InterfaceEndpointClient(
542 controller_->CreateLocalEndpointHandle(mojo::kMasterInterfaceId),
543 nullptr,
544 base::MakeUnique<typename mojom::Bootstrap::ResponseValidator_>(),
545 false, base::ThreadTaskRunnerHandle::Get()));
546 proxy_.reset(new mojom::BootstrapProxy(endpoint_client_.get()));
547 proxy_->serialization_context()->group_controller = controller_;
548 }
549
550 void set_connection_error_handler(const base::Closure& handler) {
551 DCHECK(endpoint_client_);
552 endpoint_client_->set_connection_error_handler(handler);
553 }
554
555 mojo::AssociatedGroup* associated_group() {
556 DCHECK(controller_);
557 return controller_->associated_group();
558 }
559
560 mojom::Bootstrap* operator->() {
561 DCHECK(proxy_);
562 return proxy_.get();
563 }
564
565 private:
566 std::unique_ptr<mojom::BootstrapProxy> proxy_;
567 scoped_refptr<ChannelAssociatedGroupController> controller_;
568 std::unique_ptr<mojo::InterfaceEndpointClient> endpoint_client_;
569
570 DISALLOW_COPY_AND_ASSIGN(BootstrapMasterProxy);
571 };
572
573 class BootstrapMasterBinding {
574 public:
575 explicit BootstrapMasterBinding(mojom::Bootstrap* impl) {
576 stub_.set_sink(impl);
577 }
578
579 ~BootstrapMasterBinding() {
580 endpoint_client_.reset();
581 if (controller_)
582 controller_->ShutDown();
583 }
584
585 void set_connection_error_handler(const base::Closure& handler) {
586 DCHECK(endpoint_client_);
587 endpoint_client_->set_connection_error_handler(handler);
588 }
589
590 void Bind(mojo::ScopedMessagePipeHandle handle) {
591 DCHECK(!controller_);
592 controller_ =
593 new ChannelAssociatedGroupController(false, std::move(handle));
594 stub_.serialization_context()->group_controller = controller_;
595
596 endpoint_client_.reset(new mojo::InterfaceEndpointClient(
597 controller_->CreateLocalEndpointHandle(mojo::kMasterInterfaceId),
598 &stub_,
599 base::MakeUnique<typename mojom::Bootstrap::RequestValidator_>(),
600 false, base::ThreadTaskRunnerHandle::Get()));
601 }
602
603 private:
604 mojom::BootstrapStub stub_;
605 scoped_refptr<ChannelAssociatedGroupController> controller_;
606 std::unique_ptr<mojo::InterfaceEndpointClient> endpoint_client_;
607
608 DISALLOW_COPY_AND_ASSIGN(BootstrapMasterBinding);
609 };
610
24 // MojoBootstrap for the server process. You should create the instance 611 // MojoBootstrap for the server process. You should create the instance
25 // using MojoBootstrap::Create(). 612 // using MojoBootstrap::Create().
26 class MojoServerBootstrap : public MojoBootstrap { 613 class MojoServerBootstrap : public MojoBootstrap {
27 public: 614 public:
28 MojoServerBootstrap(); 615 MojoServerBootstrap();
29 616
30 private: 617 private:
31 // MojoBootstrap implementation. 618 // MojoBootstrap implementation.
32 void Connect() override; 619 void Connect() override;
33 620
34 void OnInitDone(int32_t peer_pid); 621 void OnInitDone(int32_t peer_pid);
35 622
36 mojom::BootstrapPtr bootstrap_; 623 BootstrapMasterProxy bootstrap_;
37 IPC::mojom::ChannelAssociatedPtrInfo send_channel_; 624 IPC::mojom::ChannelAssociatedPtrInfo send_channel_;
38 IPC::mojom::ChannelAssociatedRequest receive_channel_request_; 625 IPC::mojom::ChannelAssociatedRequest receive_channel_request_;
39 626
40 DISALLOW_COPY_AND_ASSIGN(MojoServerBootstrap); 627 DISALLOW_COPY_AND_ASSIGN(MojoServerBootstrap);
41 }; 628 };
42 629
43 MojoServerBootstrap::MojoServerBootstrap() = default; 630 MojoServerBootstrap::MojoServerBootstrap() = default;
44 631
45 void MojoServerBootstrap::Connect() { 632 void MojoServerBootstrap::Connect() {
46 DCHECK_EQ(state(), STATE_INITIALIZED); 633 DCHECK_EQ(state(), STATE_INITIALIZED);
47 634
48 bootstrap_.Bind(mojom::BootstrapPtrInfo(TakeHandle(), 0)); 635 bootstrap_.Bind(TakeHandle());
49 bootstrap_.set_connection_error_handler( 636 bootstrap_.set_connection_error_handler(
50 base::Bind(&MojoServerBootstrap::Fail, base::Unretained(this))); 637 base::Bind(&MojoServerBootstrap::Fail, base::Unretained(this)));
51 638
52 IPC::mojom::ChannelAssociatedRequest send_channel_request; 639 IPC::mojom::ChannelAssociatedRequest send_channel_request;
53 IPC::mojom::ChannelAssociatedPtrInfo receive_channel; 640 IPC::mojom::ChannelAssociatedPtrInfo receive_channel;
54 641
55 bootstrap_.associated_group()->CreateAssociatedInterface( 642 bootstrap_.associated_group()->CreateAssociatedInterface(
56 mojo::AssociatedGroup::WILL_PASS_REQUEST, &send_channel_, 643 mojo::AssociatedGroup::WILL_PASS_REQUEST, &send_channel_,
57 &send_channel_request); 644 &send_channel_request);
58 bootstrap_.associated_group()->CreateAssociatedInterface( 645 bootstrap_.associated_group()->CreateAssociatedInterface(
(...skipping 30 matching lines...) Expand all
89 private: 676 private:
90 // MojoBootstrap implementation. 677 // MojoBootstrap implementation.
91 void Connect() override; 678 void Connect() override;
92 679
93 // mojom::Bootstrap implementation. 680 // mojom::Bootstrap implementation.
94 void Init(mojom::ChannelAssociatedRequest receive_channel, 681 void Init(mojom::ChannelAssociatedRequest receive_channel,
95 mojom::ChannelAssociatedPtrInfo send_channel, 682 mojom::ChannelAssociatedPtrInfo send_channel,
96 int32_t peer_pid, 683 int32_t peer_pid,
97 const InitCallback& callback) override; 684 const InitCallback& callback) override;
98 685
99 mojo::Binding<mojom::Bootstrap> binding_; 686 BootstrapMasterBinding binding_;
100 687
101 DISALLOW_COPY_AND_ASSIGN(MojoClientBootstrap); 688 DISALLOW_COPY_AND_ASSIGN(MojoClientBootstrap);
102 }; 689 };
103 690
104 MojoClientBootstrap::MojoClientBootstrap() : binding_(this) {} 691 MojoClientBootstrap::MojoClientBootstrap() : binding_(this) {}
105 692
106 void MojoClientBootstrap::Connect() { 693 void MojoClientBootstrap::Connect() {
107 binding_.Bind(TakeHandle()); 694 binding_.Bind(TakeHandle());
108 binding_.set_connection_error_handler( 695 binding_.set_connection_error_handler(
109 base::Bind(&MojoClientBootstrap::Fail, base::Unretained(this))); 696 base::Bind(&MojoClientBootstrap::Fail, base::Unretained(this)));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 756
170 bool MojoBootstrap::HasFailed() const { 757 bool MojoBootstrap::HasFailed() const {
171 return state() == STATE_ERROR; 758 return state() == STATE_ERROR;
172 } 759 }
173 760
174 mojo::ScopedMessagePipeHandle MojoBootstrap::TakeHandle() { 761 mojo::ScopedMessagePipeHandle MojoBootstrap::TakeHandle() {
175 return std::move(handle_); 762 return std::move(handle_);
176 } 763 }
177 764
178 } // namespace IPC 765 } // 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