| OLD | NEW |
| 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 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 } | 149 } |
| 150 | 150 |
| 151 mojo::ScopedInterfaceEndpointHandle CreateLocalEndpointHandle( | 151 mojo::ScopedInterfaceEndpointHandle CreateLocalEndpointHandle( |
| 152 mojo::InterfaceId id) override { | 152 mojo::InterfaceId id) override { |
| 153 if (!mojo::IsValidInterfaceId(id)) | 153 if (!mojo::IsValidInterfaceId(id)) |
| 154 return mojo::ScopedInterfaceEndpointHandle(); | 154 return mojo::ScopedInterfaceEndpointHandle(); |
| 155 | 155 |
| 156 base::AutoLock locker(lock_); | 156 base::AutoLock locker(lock_); |
| 157 bool inserted = false; | 157 bool inserted = false; |
| 158 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); | 158 Endpoint* endpoint = FindOrInsertEndpoint(id, &inserted); |
| 159 if (inserted && encountered_error_) | 159 if (inserted) { |
| 160 endpoint->set_peer_closed(); | 160 DCHECK(!endpoint->handle_created()); |
| 161 if (encountered_error_) |
| 162 endpoint->set_peer_closed(); |
| 163 } else { |
| 164 if (endpoint->handle_created()) |
| 165 return mojo::ScopedInterfaceEndpointHandle(); |
| 166 } |
| 161 | 167 |
| 168 endpoint->set_handle_created(); |
| 162 return CreateScopedInterfaceEndpointHandle(id, true); | 169 return CreateScopedInterfaceEndpointHandle(id, true); |
| 163 } | 170 } |
| 164 | 171 |
| 165 void CloseEndpointHandle( | 172 void CloseEndpointHandle( |
| 166 mojo::InterfaceId id, | 173 mojo::InterfaceId id, |
| 167 bool is_local, | 174 bool is_local, |
| 168 const base::Optional<mojo::DisconnectReason>& reason) override { | 175 const base::Optional<mojo::DisconnectReason>& reason) override { |
| 169 if (!mojo::IsValidInterfaceId(id)) | 176 if (!mojo::IsValidInterfaceId(id)) |
| 170 return; | 177 return; |
| 171 | 178 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 base::Bind(&ChannelAssociatedGroupController::RaiseError, this)); | 240 base::Bind(&ChannelAssociatedGroupController::RaiseError, this)); |
| 234 } | 241 } |
| 235 } | 242 } |
| 236 | 243 |
| 237 private: | 244 private: |
| 238 class Endpoint; | 245 class Endpoint; |
| 239 class ControlMessageProxyThunk; | 246 class ControlMessageProxyThunk; |
| 240 friend class Endpoint; | 247 friend class Endpoint; |
| 241 friend class ControlMessageProxyThunk; | 248 friend class ControlMessageProxyThunk; |
| 242 | 249 |
| 250 // Message objects cannot be destroyed under the controller's lock, if they |
| 251 // contain ScopedInterfaceEndpointHandle objects. |
| 252 // IncomingMessageWrapper is used to wrap messages which haven't got the |
| 253 // payload interface IDs deserialized into ScopedInterfaceEndpointHandles. |
| 254 // Wrapper objects are always destroyed under the controller's lock. When a |
| 255 // wrapper is destroyed and the message hasn't been consumed, the wrapper is |
| 256 // responsible to send endpoint closed notifications. |
| 257 class IncomingMessageWrapper { |
| 258 public: |
| 259 IncomingMessageWrapper() = default; |
| 260 |
| 261 IncomingMessageWrapper(ChannelAssociatedGroupController* controller, |
| 262 mojo::Message* message) |
| 263 : controller_(controller), value_(std::move(*message)) { |
| 264 DCHECK(value_.associated_endpoint_handles()->empty()); |
| 265 } |
| 266 |
| 267 IncomingMessageWrapper(IncomingMessageWrapper&& other) |
| 268 : controller_(other.controller_), value_(std::move(other.value_)) {} |
| 269 |
| 270 ~IncomingMessageWrapper() { |
| 271 if (value_.IsNull()) |
| 272 return; |
| 273 |
| 274 controller_->lock_.AssertAcquired(); |
| 275 |
| 276 uint32_t num_ids = value_.payload_num_interface_ids(); |
| 277 const uint32_t* ids = value_.payload_interface_ids(); |
| 278 for (uint32_t i = 0; i < num_ids; ++i) { |
| 279 base::AutoUnlock unlocker(controller_->lock_); |
| 280 controller_->control_message_proxy_.NotifyPeerEndpointClosed( |
| 281 ids[i], base::nullopt); |
| 282 } |
| 283 } |
| 284 |
| 285 IncomingMessageWrapper& operator=(IncomingMessageWrapper&& other) { |
| 286 controller_ = other.controller_; |
| 287 value_ = std::move(other.value_); |
| 288 return *this; |
| 289 } |
| 290 |
| 291 // Must be called outside of the controller's lock. |
| 292 bool TakeMessage(mojo::Message* output) { |
| 293 DCHECK(!value_.IsNull()); |
| 294 |
| 295 *output = std::move(value_); |
| 296 return output->DeserializeAssociatedEndpointHandles(controller_); |
| 297 } |
| 298 |
| 299 const mojo::Message& value() const { return value_; } |
| 300 |
| 301 private: |
| 302 ChannelAssociatedGroupController* controller_ = nullptr; |
| 303 // It must not hold any ScopedInterfaceEndpointHandle objects. |
| 304 mojo::Message value_; |
| 305 |
| 306 DISALLOW_COPY_AND_ASSIGN(IncomingMessageWrapper); |
| 307 }; |
| 308 |
| 243 class Endpoint : public base::RefCountedThreadSafe<Endpoint>, | 309 class Endpoint : public base::RefCountedThreadSafe<Endpoint>, |
| 244 public mojo::InterfaceEndpointController { | 310 public mojo::InterfaceEndpointController { |
| 245 public: | 311 public: |
| 246 Endpoint(ChannelAssociatedGroupController* controller, mojo::InterfaceId id) | 312 Endpoint(ChannelAssociatedGroupController* controller, mojo::InterfaceId id) |
| 247 : controller_(controller), id_(id) {} | 313 : controller_(controller), id_(id) {} |
| 248 | 314 |
| 249 mojo::InterfaceId id() const { return id_; } | 315 mojo::InterfaceId id() const { return id_; } |
| 250 | 316 |
| 251 bool closed() const { | 317 bool closed() const { |
| 252 controller_->lock_.AssertAcquired(); | 318 controller_->lock_.AssertAcquired(); |
| 253 return closed_; | 319 return closed_; |
| 254 } | 320 } |
| 255 | 321 |
| 256 void set_closed() { | 322 void set_closed() { |
| 257 controller_->lock_.AssertAcquired(); | 323 controller_->lock_.AssertAcquired(); |
| 258 closed_ = true; | 324 closed_ = true; |
| 259 } | 325 } |
| 260 | 326 |
| 261 bool peer_closed() const { | 327 bool peer_closed() const { |
| 262 controller_->lock_.AssertAcquired(); | 328 controller_->lock_.AssertAcquired(); |
| 263 return peer_closed_; | 329 return peer_closed_; |
| 264 } | 330 } |
| 265 | 331 |
| 266 void set_peer_closed() { | 332 void set_peer_closed() { |
| 267 controller_->lock_.AssertAcquired(); | 333 controller_->lock_.AssertAcquired(); |
| 268 peer_closed_ = true; | 334 peer_closed_ = true; |
| 269 } | 335 } |
| 270 | 336 |
| 337 bool handle_created() const { |
| 338 controller_->lock_.AssertAcquired(); |
| 339 return handle_created_; |
| 340 } |
| 341 |
| 342 void set_handle_created() { |
| 343 controller_->lock_.AssertAcquired(); |
| 344 handle_created_ = true; |
| 345 } |
| 346 |
| 271 const base::Optional<mojo::DisconnectReason>& disconnect_reason() const { | 347 const base::Optional<mojo::DisconnectReason>& disconnect_reason() const { |
| 272 return disconnect_reason_; | 348 return disconnect_reason_; |
| 273 } | 349 } |
| 274 | 350 |
| 275 void set_disconnect_reason( | 351 void set_disconnect_reason( |
| 276 const base::Optional<mojo::DisconnectReason>& disconnect_reason) { | 352 const base::Optional<mojo::DisconnectReason>& disconnect_reason) { |
| 277 disconnect_reason_ = disconnect_reason; | 353 disconnect_reason_ = disconnect_reason; |
| 278 } | 354 } |
| 279 | 355 |
| 280 base::SingleThreadTaskRunner* task_runner() const { | 356 base::SingleThreadTaskRunner* task_runner() const { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 301 controller_->lock_.AssertAcquired(); | 377 controller_->lock_.AssertAcquired(); |
| 302 DCHECK(client_); | 378 DCHECK(client_); |
| 303 DCHECK(task_runner_->BelongsToCurrentThread()); | 379 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 304 DCHECK(!closed_); | 380 DCHECK(!closed_); |
| 305 | 381 |
| 306 task_runner_ = nullptr; | 382 task_runner_ = nullptr; |
| 307 client_ = nullptr; | 383 client_ = nullptr; |
| 308 sync_watcher_.reset(); | 384 sync_watcher_.reset(); |
| 309 } | 385 } |
| 310 | 386 |
| 311 uint32_t EnqueueSyncMessage(mojo::Message message) { | 387 uint32_t EnqueueSyncMessage(IncomingMessageWrapper message) { |
| 312 controller_->lock_.AssertAcquired(); | 388 controller_->lock_.AssertAcquired(); |
| 313 uint32_t id = GenerateSyncMessageId(); | 389 uint32_t id = GenerateSyncMessageId(); |
| 314 sync_messages_.emplace(id, std::move(message)); | 390 sync_messages_.emplace(id, std::move(message)); |
| 315 SignalSyncMessageEvent(); | 391 SignalSyncMessageEvent(); |
| 316 return id; | 392 return id; |
| 317 } | 393 } |
| 318 | 394 |
| 319 void SignalSyncMessageEvent() { | 395 void SignalSyncMessageEvent() { |
| 320 controller_->lock_.AssertAcquired(); | 396 controller_->lock_.AssertAcquired(); |
| 321 EnsureSyncMessageEventExists(); | 397 EnsureSyncMessageEventExists(); |
| 322 sync_message_event_->Signal(); | 398 sync_message_event_->Signal(); |
| 323 } | 399 } |
| 324 | 400 |
| 325 mojo::Message PopSyncMessage(uint32_t id) { | 401 IncomingMessageWrapper PopSyncMessage(uint32_t id) { |
| 326 controller_->lock_.AssertAcquired(); | 402 controller_->lock_.AssertAcquired(); |
| 327 if (sync_messages_.empty() || sync_messages_.front().first != id) | 403 if (sync_messages_.empty() || sync_messages_.front().first != id) |
| 328 return mojo::Message(); | 404 return IncomingMessageWrapper(); |
| 329 mojo::Message message = std::move(sync_messages_.front().second); | 405 IncomingMessageWrapper message = std::move(sync_messages_.front().second); |
| 330 sync_messages_.pop(); | 406 sync_messages_.pop(); |
| 331 return message; | 407 return message; |
| 332 } | 408 } |
| 333 | 409 |
| 334 // mojo::InterfaceEndpointController: | 410 // mojo::InterfaceEndpointController: |
| 335 bool SendMessage(mojo::Message* message) override { | 411 bool SendMessage(mojo::Message* message) override { |
| 336 DCHECK(task_runner_->BelongsToCurrentThread()); | 412 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 337 message->set_interface_id(id_); | 413 message->set_interface_id(id_); |
| 414 message->SerializeAssociatedEndpointHandles(controller_); |
| 338 return controller_->SendMessage(message); | 415 return controller_->SendMessage(message); |
| 339 } | 416 } |
| 340 | 417 |
| 341 void AllowWokenUpBySyncWatchOnSameThread() override { | 418 void AllowWokenUpBySyncWatchOnSameThread() override { |
| 342 DCHECK(task_runner_->BelongsToCurrentThread()); | 419 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 343 | 420 |
| 344 EnsureSyncWatcherExists(); | 421 EnsureSyncWatcherExists(); |
| 345 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); | 422 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); |
| 346 } | 423 } |
| 347 | 424 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 373 | 450 |
| 374 scoped_refptr<Endpoint> keepalive(this); | 451 scoped_refptr<Endpoint> keepalive(this); |
| 375 scoped_refptr<AssociatedGroupController> controller_keepalive( | 452 scoped_refptr<AssociatedGroupController> controller_keepalive( |
| 376 controller_); | 453 controller_); |
| 377 | 454 |
| 378 bool reset_sync_watcher = false; | 455 bool reset_sync_watcher = false; |
| 379 { | 456 { |
| 380 base::AutoLock locker(controller_->lock_); | 457 base::AutoLock locker(controller_->lock_); |
| 381 bool more_to_process = false; | 458 bool more_to_process = false; |
| 382 if (!sync_messages_.empty()) { | 459 if (!sync_messages_.empty()) { |
| 383 mojo::Message message = std::move(sync_messages_.front().second); | 460 IncomingMessageWrapper message_wrapper = |
| 461 std::move(sync_messages_.front().second); |
| 384 sync_messages_.pop(); | 462 sync_messages_.pop(); |
| 385 | 463 |
| 386 bool dispatch_succeeded; | 464 bool dispatch_succeeded; |
| 387 mojo::InterfaceEndpointClient* client = client_; | 465 mojo::InterfaceEndpointClient* client = client_; |
| 388 { | 466 { |
| 389 base::AutoUnlock unlocker(controller_->lock_); | 467 base::AutoUnlock unlocker(controller_->lock_); |
| 390 dispatch_succeeded = client->HandleIncomingMessage(&message); | 468 mojo::Message message; |
| 469 dispatch_succeeded = message_wrapper.TakeMessage(&message) && |
| 470 client->HandleIncomingMessage(&message); |
| 391 } | 471 } |
| 392 | 472 |
| 393 if (!sync_messages_.empty()) | 473 if (!sync_messages_.empty()) |
| 394 more_to_process = true; | 474 more_to_process = true; |
| 395 | 475 |
| 396 if (!dispatch_succeeded) | 476 if (!dispatch_succeeded) |
| 397 controller_->RaiseError(); | 477 controller_->RaiseError(); |
| 398 } | 478 } |
| 399 | 479 |
| 400 if (!more_to_process) | 480 if (!more_to_process) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 uint32_t id = next_sync_message_id_++; | 522 uint32_t id = next_sync_message_id_++; |
| 443 DCHECK(sync_messages_.empty() || sync_messages_.front().first != id); | 523 DCHECK(sync_messages_.empty() || sync_messages_.front().first != id); |
| 444 return id; | 524 return id; |
| 445 } | 525 } |
| 446 | 526 |
| 447 ChannelAssociatedGroupController* const controller_; | 527 ChannelAssociatedGroupController* const controller_; |
| 448 const mojo::InterfaceId id_; | 528 const mojo::InterfaceId id_; |
| 449 | 529 |
| 450 bool closed_ = false; | 530 bool closed_ = false; |
| 451 bool peer_closed_ = false; | 531 bool peer_closed_ = false; |
| 532 bool handle_created_ = false; |
| 452 base::Optional<mojo::DisconnectReason> disconnect_reason_; | 533 base::Optional<mojo::DisconnectReason> disconnect_reason_; |
| 453 mojo::InterfaceEndpointClient* client_ = nullptr; | 534 mojo::InterfaceEndpointClient* client_ = nullptr; |
| 454 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | 535 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 455 std::unique_ptr<mojo::SyncHandleWatcher> sync_watcher_; | 536 std::unique_ptr<mojo::SyncHandleWatcher> sync_watcher_; |
| 456 std::unique_ptr<MojoEvent> sync_message_event_; | 537 std::unique_ptr<MojoEvent> sync_message_event_; |
| 457 std::queue<std::pair<uint32_t, mojo::Message>> sync_messages_; | 538 std::queue<std::pair<uint32_t, IncomingMessageWrapper>> sync_messages_; |
| 458 uint32_t next_sync_message_id_ = 0; | 539 uint32_t next_sync_message_id_ = 0; |
| 459 | 540 |
| 460 DISALLOW_COPY_AND_ASSIGN(Endpoint); | 541 DISALLOW_COPY_AND_ASSIGN(Endpoint); |
| 461 }; | 542 }; |
| 462 | 543 |
| 463 class ControlMessageProxyThunk : public MessageReceiver { | 544 class ControlMessageProxyThunk : public MessageReceiver { |
| 464 public: | 545 public: |
| 465 explicit ControlMessageProxyThunk( | 546 explicit ControlMessageProxyThunk( |
| 466 ChannelAssociatedGroupController* controller) | 547 ChannelAssociatedGroupController* controller) |
| 467 : controller_(controller) {} | 548 : controller_(controller) {} |
| 468 | 549 |
| 469 private: | 550 private: |
| 470 // MessageReceiver: | 551 // MessageReceiver: |
| 471 bool Accept(mojo::Message* message) override { | 552 bool Accept(mojo::Message* message) override { |
| 553 message->SerializeAssociatedEndpointHandles(controller_); |
| 472 return controller_->SendMessage(message); | 554 return controller_->SendMessage(message); |
| 473 } | 555 } |
| 474 | 556 |
| 475 ChannelAssociatedGroupController* controller_; | 557 ChannelAssociatedGroupController* controller_; |
| 476 | 558 |
| 477 DISALLOW_COPY_AND_ASSIGN(ControlMessageProxyThunk); | 559 DISALLOW_COPY_AND_ASSIGN(ControlMessageProxyThunk); |
| 478 }; | 560 }; |
| 479 | 561 |
| 480 ~ChannelAssociatedGroupController() override { | 562 ~ChannelAssociatedGroupController() override { |
| 481 DCHECK(!connector_); | 563 DCHECK(!connector_); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 endpoints_.insert({ id, endpoint }); | 697 endpoints_.insert({ id, endpoint }); |
| 616 if (inserted) | 698 if (inserted) |
| 617 *inserted = true; | 699 *inserted = true; |
| 618 return endpoint; | 700 return endpoint; |
| 619 } | 701 } |
| 620 | 702 |
| 621 // mojo::MessageReceiver: | 703 // mojo::MessageReceiver: |
| 622 bool Accept(mojo::Message* message) override { | 704 bool Accept(mojo::Message* message) override { |
| 623 DCHECK(thread_checker_.CalledOnValidThread()); | 705 DCHECK(thread_checker_.CalledOnValidThread()); |
| 624 | 706 |
| 625 if (mojo::PipeControlMessageHandler::IsPipeControlMessage(message)) | 707 if (mojo::PipeControlMessageHandler::IsPipeControlMessage(message)) { |
| 626 return control_message_handler_.Accept(message); | 708 return message->DeserializeAssociatedEndpointHandles(this) && |
| 709 control_message_handler_.Accept(message); |
| 710 } |
| 627 | 711 |
| 628 mojo::InterfaceId id = message->interface_id(); | 712 mojo::InterfaceId id = message->interface_id(); |
| 629 DCHECK(mojo::IsValidInterfaceId(id)); | 713 DCHECK(mojo::IsValidInterfaceId(id)); |
| 630 | 714 |
| 631 base::AutoLock locker(lock_); | 715 base::AutoLock locker(lock_); |
| 632 Endpoint* endpoint = GetEndpointForDispatch(id, true /* create */); | 716 Endpoint* endpoint = GetEndpointForDispatch(id, true /* create */); |
| 633 mojo::InterfaceEndpointClient* client = | 717 mojo::InterfaceEndpointClient* client = |
| 634 endpoint ? endpoint->client() : nullptr; | 718 endpoint ? endpoint->client() : nullptr; |
| 635 if (!client || !endpoint->task_runner()->BelongsToCurrentThread()) { | 719 if (!client || !endpoint->task_runner()->BelongsToCurrentThread()) { |
| 636 // No client has been bound yet or the client runs tasks on another | 720 // No client has been bound yet or the client runs tasks on another |
| 637 // thread. We assume the other thread must always be the one on which | 721 // thread. We assume the other thread must always be the one on which |
| 638 // |proxy_task_runner_| runs tasks, since that's the only valid scenario. | 722 // |proxy_task_runner_| runs tasks, since that's the only valid scenario. |
| 639 // | 723 // |
| 640 // If the client is not yet bound, it must be bound by the time this task | 724 // If the client is not yet bound, it must be bound by the time this task |
| 641 // runs or else it's programmer error. | 725 // runs or else it's programmer error. |
| 642 DCHECK(proxy_task_runner_); | 726 DCHECK(proxy_task_runner_); |
| 643 | 727 |
| 644 if (message->has_flag(mojo::Message::kFlagIsSync)) { | 728 if (message->has_flag(mojo::Message::kFlagIsSync)) { |
| 729 IncomingMessageWrapper message_wrapper(this, message); |
| 645 // Sync messages may need to be handled by the endpoint if it's blocking | 730 // Sync messages may need to be handled by the endpoint if it's blocking |
| 646 // on a sync reply. We pass ownership of the message to the endpoint's | 731 // on a sync reply. We pass ownership of the message to the endpoint's |
| 647 // sync message queue. If the endpoint was blocking, it will dequeue the | 732 // sync message queue. If the endpoint was blocking, it will dequeue the |
| 648 // message and dispatch it. Otherwise the posted |AcceptSyncMessage()| | 733 // message and dispatch it. Otherwise the posted |AcceptSyncMessage()| |
| 649 // call will dequeue the message and dispatch it. | 734 // call will dequeue the message and dispatch it. |
| 650 uint32_t message_id = endpoint->EnqueueSyncMessage(std::move(*message)); | 735 uint32_t message_id = |
| 736 endpoint->EnqueueSyncMessage(std::move(message_wrapper)); |
| 651 proxy_task_runner_->PostTask( | 737 proxy_task_runner_->PostTask( |
| 652 FROM_HERE, | 738 FROM_HERE, |
| 653 base::Bind(&ChannelAssociatedGroupController::AcceptSyncMessage, | 739 base::Bind(&ChannelAssociatedGroupController::AcceptSyncMessage, |
| 654 this, id, message_id)); | 740 this, id, message_id)); |
| 655 return true; | 741 return true; |
| 656 } | 742 } |
| 657 | 743 |
| 658 proxy_task_runner_->PostTask( | 744 proxy_task_runner_->PostTask( |
| 659 FROM_HERE, | 745 FROM_HERE, |
| 660 base::Bind(&ChannelAssociatedGroupController::AcceptOnProxyThread, | 746 base::Bind(&ChannelAssociatedGroupController::AcceptOnProxyThread, |
| 661 this, base::Passed(message))); | 747 this, base::Passed(message))); |
| 662 return true; | 748 return true; |
| 663 } | 749 } |
| 664 | 750 |
| 665 // We do not expect to receive sync responses on the master endpoint thread. | 751 // We do not expect to receive sync responses on the master endpoint thread. |
| 666 // If it's happening, it's a bug. | 752 // If it's happening, it's a bug. |
| 667 DCHECK(!message->has_flag(mojo::Message::kFlagIsSync) || | 753 DCHECK(!message->has_flag(mojo::Message::kFlagIsSync) || |
| 668 !message->has_flag(mojo::Message::kFlagIsResponse)); | 754 !message->has_flag(mojo::Message::kFlagIsResponse)); |
| 669 | 755 |
| 670 base::AutoUnlock unlocker(lock_); | 756 base::AutoUnlock unlocker(lock_); |
| 671 return client->HandleIncomingMessage(message); | 757 return message->DeserializeAssociatedEndpointHandles(this) && |
| 758 client->HandleIncomingMessage(message); |
| 672 } | 759 } |
| 673 | 760 |
| 674 void AcceptOnProxyThread(mojo::Message message) { | 761 void AcceptOnProxyThread(mojo::Message message) { |
| 675 DCHECK(proxy_task_runner_->BelongsToCurrentThread()); | 762 DCHECK(proxy_task_runner_->BelongsToCurrentThread()); |
| 676 | 763 |
| 677 mojo::InterfaceId id = message.interface_id(); | 764 mojo::InterfaceId id = message.interface_id(); |
| 678 DCHECK(mojo::IsValidInterfaceId(id) && !mojo::IsMasterInterfaceId(id)); | 765 DCHECK(mojo::IsValidInterfaceId(id) && !mojo::IsMasterInterfaceId(id)); |
| 679 | 766 |
| 680 base::AutoLock locker(lock_); | 767 base::AutoLock locker(lock_); |
| 768 IncomingMessageWrapper message_wrapper(this, &message); |
| 769 |
| 681 Endpoint* endpoint = GetEndpointForDispatch(id, false /* create */); | 770 Endpoint* endpoint = GetEndpointForDispatch(id, false /* create */); |
| 682 if (!endpoint) | 771 if (!endpoint) |
| 683 return; | 772 return; |
| 684 | 773 |
| 685 mojo::InterfaceEndpointClient* client = endpoint->client(); | 774 mojo::InterfaceEndpointClient* client = endpoint->client(); |
| 686 if (!client) | 775 if (!client) |
| 687 return; | 776 return; |
| 688 | 777 |
| 689 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); | 778 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); |
| 690 | 779 |
| 691 // Sync messages should never make their way to this method. | 780 // Sync messages should never make their way to this method. |
| 692 DCHECK(!message.has_flag(mojo::Message::kFlagIsSync)); | 781 DCHECK(!message_wrapper.value().has_flag(mojo::Message::kFlagIsSync)); |
| 693 | 782 |
| 694 bool result = false; | 783 bool result = false; |
| 695 { | 784 { |
| 696 base::AutoUnlock unlocker(lock_); | 785 base::AutoUnlock unlocker(lock_); |
| 697 result = client->HandleIncomingMessage(&message); | 786 mojo::Message message; |
| 787 result = message_wrapper.TakeMessage(&message) && |
| 788 client->HandleIncomingMessage(&message); |
| 698 } | 789 } |
| 699 | 790 |
| 700 if (!result) | 791 if (!result) |
| 701 RaiseError(); | 792 RaiseError(); |
| 702 } | 793 } |
| 703 | 794 |
| 704 void AcceptSyncMessage(mojo::InterfaceId interface_id, uint32_t message_id) { | 795 void AcceptSyncMessage(mojo::InterfaceId interface_id, uint32_t message_id) { |
| 705 DCHECK(proxy_task_runner_->BelongsToCurrentThread()); | 796 DCHECK(proxy_task_runner_->BelongsToCurrentThread()); |
| 706 | 797 |
| 707 base::AutoLock locker(lock_); | 798 base::AutoLock locker(lock_); |
| 708 Endpoint* endpoint = | 799 Endpoint* endpoint = |
| 709 GetEndpointForDispatch(interface_id, false /* create */); | 800 GetEndpointForDispatch(interface_id, false /* create */); |
| 710 if (!endpoint) | 801 if (!endpoint) |
| 711 return; | 802 return; |
| 712 | 803 |
| 713 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); | 804 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); |
| 714 mojo::Message message = endpoint->PopSyncMessage(message_id); | 805 IncomingMessageWrapper message_wrapper = |
| 806 endpoint->PopSyncMessage(message_id); |
| 715 | 807 |
| 716 // The message must have already been dequeued by the endpoint waking up | 808 // The message must have already been dequeued by the endpoint waking up |
| 717 // from a sync wait. Nothing to do. | 809 // from a sync wait. Nothing to do. |
| 718 if (message.IsNull()) | 810 if (message_wrapper.value().IsNull()) |
| 719 return; | 811 return; |
| 720 | 812 |
| 721 mojo::InterfaceEndpointClient* client = endpoint->client(); | 813 mojo::InterfaceEndpointClient* client = endpoint->client(); |
| 722 if (!client) | 814 if (!client) |
| 723 return; | 815 return; |
| 724 | 816 |
| 725 bool result = false; | 817 bool result = false; |
| 726 { | 818 { |
| 727 base::AutoUnlock unlocker(lock_); | 819 base::AutoUnlock unlocker(lock_); |
| 728 result = client->HandleIncomingMessage(&message); | 820 mojo::Message message; |
| 821 result = message_wrapper.TakeMessage(&message) && |
| 822 client->HandleIncomingMessage(&message); |
| 729 } | 823 } |
| 730 | 824 |
| 731 if (!result) | 825 if (!result) |
| 732 RaiseError(); | 826 RaiseError(); |
| 733 } | 827 } |
| 734 | 828 |
| 735 Endpoint* GetEndpointForDispatch(mojo::InterfaceId id, bool create) { | 829 Endpoint* GetEndpointForDispatch(mojo::InterfaceId id, bool create) { |
| 736 lock_.AssertAcquired(); | 830 lock_.AssertAcquired(); |
| 737 auto iter = endpoints_.find(id); | 831 auto iter = endpoints_.find(id); |
| 738 if (iter != endpoints_.end()) | 832 if (iter != endpoints_.end()) |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 Channel::Mode mode, | 972 Channel::Mode mode, |
| 879 Delegate* delegate, | 973 Delegate* delegate, |
| 880 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { | 974 const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner) { |
| 881 return base::MakeUnique<MojoBootstrapImpl>( | 975 return base::MakeUnique<MojoBootstrapImpl>( |
| 882 std::move(handle), delegate, | 976 std::move(handle), delegate, |
| 883 new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, | 977 new ChannelAssociatedGroupController(mode == Channel::MODE_SERVER, |
| 884 ipc_task_runner)); | 978 ipc_task_runner)); |
| 885 } | 979 } |
| 886 | 980 |
| 887 } // namespace IPC | 981 } // namespace IPC |
| OLD | NEW |