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 3 // found in the LICENSE file. 4 5 #include "mojo/public/cpp/bindings/lib/router.h" 6 7 #include "mojo/public/cpp/environment/logging.h" 8 9 namespace mojo { 10 namespace internal { 11 12 // ---------------------------------------------------------------------------- 13 14 class ResponderThunk : public MessageReceiver { 15 public: 16 explicit ResponderThunk(const SharedData<Router*>& router) 17 : router_(router) { 18 } 19 virtual ~ResponderThunk() { 20 } 21 22 // MessageReceiver implementation: 23 virtual bool Accept(Message* message) MOJO_OVERRIDE { 24 MOJO_DCHECK(message->has_flag(kMessageIsResponse)); 25 26 bool result = false; 27 28 Router* router = router_.value(); 29 if (router) 30 result = router->Accept(message); 31 32 return result; 33 } 34 35 private: 36 SharedData<Router*> router_; 37 }; 38 39 // ---------------------------------------------------------------------------- 40 41 Router::HandleIncomingMessageThunk::HandleIncomingMessageThunk(Router* router) 42 : router_(router) { 43 } 44 45 Router::HandleIncomingMessageThunk::~HandleIncomingMessageThunk() { 46 } 47 48 bool Router::HandleIncomingMessageThunk::Accept(Message* message) { 49 return router_->HandleIncomingMessage(message); 50 } 51 52 // ---------------------------------------------------------------------------- 53 54 Router::Router(ScopedMessagePipeHandle message_pipe, 55 FilterChain filters, 56 const MojoAsyncWaiter* waiter) 57 : thunk_(this), 58 filters_(filters.Pass()), 59 connector_(message_pipe.Pass(), waiter), 60 weak_self_(this), 61 incoming_receiver_(NULL), 62 next_request_id_(0), 63 testing_mode_(false) { 64 filters_.SetSink(&thunk_); 65 connector_.set_incoming_receiver(filters_.GetHead()); 66 } 67 68 Router::~Router() { 69 weak_self_.set_value(NULL); 70 71 for (ResponderMap::const_iterator i = responders_.begin(); 72 i != responders_.end(); ++i) { 73 delete i->second; 74 } 75 } 76 77 bool Router::Accept(Message* message) { 78 MOJO_DCHECK(!message->has_flag(kMessageExpectsResponse)); 79 return connector_.Accept(message); 80 } 81 82 bool Router::AcceptWithResponder(Message* message, 83 MessageReceiver* responder) { 84 MOJO_DCHECK(message->has_flag(kMessageExpectsResponse)); 85 86 // Reserve 0 in case we want it to convey special meaning in the future. 87 uint64_t request_id = next_request_id_++; 88 if (request_id == 0) 89 request_id = next_request_id_++; 90 91 message->set_request_id(request_id); 92 if (!connector_.Accept(message)) 93 return false; 94 95 // We assume ownership of |responder|. 96 responders_[request_id] = responder; 97 return true; 98 } 99 100 void Router::EnableTestingMode() { 101 testing_mode_ = true; 102 connector_.set_enforce_errors_from_incoming_receiver(false); 103 } 104 105 bool Router::HandleIncomingMessage(Message* message) { 106 if (message->has_flag(kMessageExpectsResponse)) { 107 if (incoming_receiver_) { 108 MessageReceiver* responder = new ResponderThunk(weak_self_); 109 bool ok = incoming_receiver_->AcceptWithResponder(message, responder); 110 if (!ok) 111 delete responder; 112 return ok; 113 } 114 115 // If we receive a request expecting a response when the client is not 116 // listening, then we have no choice but to tear down the pipe. 117 connector_.CloseMessagePipe(); 118 } else if (message->has_flag(kMessageIsResponse)) { 119 uint64_t request_id = message->request_id(); 120 ResponderMap::iterator it = responders_.find(request_id); 121 if (it == responders_.end()) { 122 MOJO_DCHECK(testing_mode_); 123 return false; 124 } 125 MessageReceiver* responder = it->second; 126 responders_.erase(it); 127 bool ok = responder->Accept(message); 128 delete responder; 129 return ok; 130 } else { 131 if (incoming_receiver_) 132 return incoming_receiver_->Accept(message); 133 // OK to drop message on the floor. 134 } 135 136 return false; 137 } 138 139 // ---------------------------------------------------------------------------- 140 141 } // namespace internal 142 } // namespace mojo 143