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

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