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

Side by Side Diff: mojo/public/cpp/bindings/lib/multiplex_router.cc

Issue 2064903002: Mojo: Report bindings validation errors via MojoNotifyBadMessage (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" 5 #include "mojo/public/cpp/bindings/lib/multiplex_router.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 } 104 }
105 105
106 // --------------------------------------------------------------------------- 106 // ---------------------------------------------------------------------------
107 // The following public methods (i.e., InterfaceEndpointController 107 // The following public methods (i.e., InterfaceEndpointController
108 // implementation) are called by the client on the same thread as the 108 // implementation) are called by the client on the same thread as the
109 // AttachClient() call. They are called outside of the router's lock. 109 // AttachClient() call. They are called outside of the router's lock.
110 110
111 bool SendMessage(Message* message) override { 111 bool SendMessage(Message* message) override {
112 DCHECK(task_runner_->BelongsToCurrentThread()); 112 DCHECK(task_runner_->BelongsToCurrentThread());
113 message->set_interface_id(id_); 113 message->set_interface_id(id_);
114 return router_->connector_.Accept(message); 114
115 Error send_error;
116 return router_->connector_.Accept(message, &send_error);
115 } 117 }
116 118
117 void AllowWokenUpBySyncWatchOnSameThread() override { 119 void AllowWokenUpBySyncWatchOnSameThread() override {
118 DCHECK(task_runner_->BelongsToCurrentThread()); 120 DCHECK(task_runner_->BelongsToCurrentThread());
119 121
120 EnsureSyncWatcherExists(); 122 EnsureSyncWatcherExists();
121 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); 123 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread();
122 } 124 }
123 125
124 bool SyncWatch(const bool* should_stop) override { 126 bool SyncWatch(const bool* should_stop) override {
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 425
424 DCHECK(IsValidInterfaceId(id)); 426 DCHECK(IsValidInterfaceId(id));
425 427
426 base::AutoLock locker(lock_); 428 base::AutoLock locker(lock_);
427 DCHECK(ContainsKey(endpoints_, id)); 429 DCHECK(ContainsKey(endpoints_, id));
428 430
429 InterfaceEndpoint* endpoint = endpoints_[id].get(); 431 InterfaceEndpoint* endpoint = endpoints_[id].get();
430 endpoint->DetachClient(); 432 endpoint->DetachClient();
431 } 433 }
432 434
433 void MultiplexRouter::RaiseError() { 435 void MultiplexRouter::RaiseError(Error error) {
434 if (task_runner_->BelongsToCurrentThread()) { 436 if (task_runner_->BelongsToCurrentThread()) {
435 connector_.RaiseError(); 437 connector_.RaiseError(std::move(error));
436 } else { 438 } else {
437 task_runner_->PostTask(FROM_HERE, 439 task_runner_->PostTask(FROM_HERE,
438 base::Bind(&MultiplexRouter::RaiseError, this)); 440 base::Bind(&MultiplexRouter::RaiseError, this,
441 base::Passed(&error)));
439 } 442 }
440 } 443 }
441 444
442 std::unique_ptr<AssociatedGroup> MultiplexRouter::CreateAssociatedGroup() { 445 std::unique_ptr<AssociatedGroup> MultiplexRouter::CreateAssociatedGroup() {
443 std::unique_ptr<AssociatedGroup> group(new AssociatedGroup); 446 std::unique_ptr<AssociatedGroup> group(new AssociatedGroup);
444 group->router_ = this; 447 group->router_ = this;
445 return group; 448 return group;
446 } 449 }
447 450
448 // static 451 // static
(...skipping 15 matching lines...) Expand all
464 base::AutoLock locker(lock_); 467 base::AutoLock locker(lock_);
465 468
466 if (endpoints_.size() > 1) 469 if (endpoints_.size() > 1)
467 return true; 470 return true;
468 if (endpoints_.size() == 0) 471 if (endpoints_.size() == 0)
469 return false; 472 return false;
470 473
471 return !ContainsKey(endpoints_, kMasterInterfaceId); 474 return !ContainsKey(endpoints_, kMasterInterfaceId);
472 } 475 }
473 476
477 void MultiplexRouter::SetMasterInterfaceName(const std::string& name) {
478 DCHECK(thread_checker_.CalledOnValidThread());
479 master_interface_name_ = name;
480 header_validator_.set_debug_info(name + " master interface header validator");
481 }
482
474 void MultiplexRouter::EnableTestingMode() { 483 void MultiplexRouter::EnableTestingMode() {
475 DCHECK(thread_checker_.CalledOnValidThread()); 484 DCHECK(thread_checker_.CalledOnValidThread());
476 base::AutoLock locker(lock_); 485 base::AutoLock locker(lock_);
477 486
478 testing_mode_ = true; 487 testing_mode_ = true;
479 connector_.set_enforce_errors_from_incoming_receiver(false); 488 connector_.set_enforce_errors_from_incoming_receiver(false);
480 } 489 }
481 490
482 bool MultiplexRouter::Accept(Message* message) { 491 bool MultiplexRouter::Accept(Message* message, Error* error) {
483 DCHECK(thread_checker_.CalledOnValidThread()); 492 DCHECK(thread_checker_.CalledOnValidThread());
484 493
485 scoped_refptr<MultiplexRouter> protector(this); 494 scoped_refptr<MultiplexRouter> protector(this);
486 base::AutoLock locker(lock_); 495 base::AutoLock locker(lock_);
487 496
488 ClientCallBehavior client_call_behavior = 497 ClientCallBehavior client_call_behavior =
489 connector_.during_sync_handle_watcher_callback() 498 connector_.during_sync_handle_watcher_callback()
490 ? ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES 499 ? ALLOW_DIRECT_CLIENT_CALLS_FOR_SYNC_MESSAGES
491 : ALLOW_DIRECT_CLIENT_CALLS; 500 : ALLOW_DIRECT_CLIENT_CALLS;
492 501
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread()); 708 DCHECK(!current_task_runner || current_task_runner->BelongsToCurrentThread());
700 lock_.AssertAcquired(); 709 lock_.AssertAcquired();
701 710
702 if (!message) { 711 if (!message) {
703 // This is a sync message and has been processed during sync handle 712 // This is a sync message and has been processed during sync handle
704 // watching. 713 // watching.
705 return true; 714 return true;
706 } 715 }
707 716
708 if (PipeControlMessageHandler::IsPipeControlMessage(message)) { 717 if (PipeControlMessageHandler::IsPipeControlMessage(message)) {
709 if (!control_message_handler_.Accept(message)) 718 Error error;
710 RaiseErrorInNonTestingMode(); 719 if (!control_message_handler_.Accept(message, &error))
720 RaiseErrorInNonTestingMode(std::move(error));
711 return true; 721 return true;
712 } 722 }
713 723
714 InterfaceId id = message->interface_id(); 724 InterfaceId id = message->interface_id();
715 DCHECK(IsValidInterfaceId(id)); 725 DCHECK(IsValidInterfaceId(id));
716 726
717 bool inserted = false; 727 bool inserted = false;
718 InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, &inserted); 728 InterfaceEndpoint* endpoint = FindOrInsertEndpoint(id, &inserted);
719 if (inserted) { 729 if (inserted) {
720 // Currently, it is legitimate to receive messages for an endpoint 730 // Currently, it is legitimate to receive messages for an endpoint
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 } 766 }
757 767
758 if (!can_direct_call) { 768 if (!can_direct_call) {
759 MaybePostToProcessTasks(endpoint->task_runner()); 769 MaybePostToProcessTasks(endpoint->task_runner());
760 return false; 770 return false;
761 } 771 }
762 772
763 DCHECK(endpoint->task_runner()->BelongsToCurrentThread()); 773 DCHECK(endpoint->task_runner()->BelongsToCurrentThread());
764 774
765 InterfaceEndpointClient* client = endpoint->client(); 775 InterfaceEndpointClient* client = endpoint->client();
776 Error error(Error::Type::NONE);
766 bool result = false; 777 bool result = false;
767 { 778 {
768 // We must unlock before calling into |client| because it may call this 779 // We must unlock before calling into |client| because it may call this
769 // object within HandleIncomingMessage(). Holding the lock will lead to 780 // object within HandleIncomingMessage(). Holding the lock will lead to
770 // deadlock. 781 // deadlock.
771 // 782 //
772 // It is safe to call into |client| without the lock. Because |client| is 783 // It is safe to call into |client| without the lock. Because |client| is
773 // always accessed on the same thread, including DetachEndpointClient(). 784 // always accessed on the same thread, including DetachEndpointClient().
774 base::AutoUnlock unlocker(lock_); 785 base::AutoUnlock unlocker(lock_);
775 result = client->HandleIncomingMessage(message); 786 result = client->HandleIncomingMessage(message, &error);
776 } 787 }
777 if (!result) 788 if (!result)
778 RaiseErrorInNonTestingMode(); 789 RaiseErrorInNonTestingMode(std::move(error));
779 790
780 return true; 791 return true;
781 } 792 }
782 793
783 void MultiplexRouter::MaybePostToProcessTasks( 794 void MultiplexRouter::MaybePostToProcessTasks(
784 base::SingleThreadTaskRunner* task_runner) { 795 base::SingleThreadTaskRunner* task_runner) {
785 lock_.AssertAcquired(); 796 lock_.AssertAcquired();
786 if (posted_to_process_tasks_) 797 if (posted_to_process_tasks_)
787 return; 798 return;
788 799
(...skipping 24 matching lines...) Expand all
813 endpoint->set_peer_closed(); 824 endpoint->set_peer_closed();
814 // If the interface endpoint is performing a sync watch, this makes sure 825 // If the interface endpoint is performing a sync watch, this makes sure
815 // it is notified and eventually exits the sync watch. 826 // it is notified and eventually exits the sync watch.
816 endpoint->SignalSyncMessageEvent(); 827 endpoint->SignalSyncMessageEvent();
817 break; 828 break;
818 } 829 }
819 if (endpoint->closed() && endpoint->peer_closed()) 830 if (endpoint->closed() && endpoint->peer_closed())
820 endpoints_.erase(endpoint->id()); 831 endpoints_.erase(endpoint->id());
821 } 832 }
822 833
823 void MultiplexRouter::RaiseErrorInNonTestingMode() { 834 void MultiplexRouter::RaiseErrorInNonTestingMode(Error error) {
824 lock_.AssertAcquired(); 835 lock_.AssertAcquired();
825 if (!testing_mode_) 836 if (!testing_mode_)
826 RaiseError(); 837 RaiseError(std::move(error));
827 } 838 }
828 839
829 MultiplexRouter::InterfaceEndpoint* MultiplexRouter::FindOrInsertEndpoint( 840 MultiplexRouter::InterfaceEndpoint* MultiplexRouter::FindOrInsertEndpoint(
830 InterfaceId id, 841 InterfaceId id,
831 bool* inserted) { 842 bool* inserted) {
832 lock_.AssertAcquired(); 843 lock_.AssertAcquired();
833 // Either |inserted| is nullptr or it points to a boolean initialized as 844 // Either |inserted| is nullptr or it points to a boolean initialized as
834 // false. 845 // false.
835 DCHECK(!inserted || !*inserted); 846 DCHECK(!inserted || !*inserted);
836 847
837 auto iter = endpoints_.find(id); 848 auto iter = endpoints_.find(id);
838 InterfaceEndpoint* endpoint; 849 InterfaceEndpoint* endpoint;
839 if (iter == endpoints_.end()) { 850 if (iter == endpoints_.end()) {
840 endpoint = new InterfaceEndpoint(this, id); 851 endpoint = new InterfaceEndpoint(this, id);
841 endpoints_[id] = endpoint; 852 endpoints_[id] = endpoint;
842 if (inserted) 853 if (inserted)
843 *inserted = true; 854 *inserted = true;
844 } else { 855 } else {
845 endpoint = iter->second.get(); 856 endpoint = iter->second.get();
846 } 857 }
847 858
848 return endpoint; 859 return endpoint;
849 } 860 }
850 861
851 } // namespace internal 862 } // namespace internal
852 } // namespace mojo 863 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698