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.
5 #include "mojo/public/cpp/bindings/lib/router.h"
10 // ----------------------------------------------------------------------------
12 class ResponderThunk : public MessageReceiver {
14 explicit ResponderThunk(const SharedData<Router*>& router)
17 virtual ~ResponderThunk() {
20 // MessageReceiver implementation:
21 virtual bool Accept(Message* message) MOJO_OVERRIDE {
22 assert(message->has_flag(kMessageIsResponse));
26 Router* router = router_.value();
28 result = router->Accept(message);
33 virtual bool AcceptWithResponder(Message* message,
34 MessageReceiver* responder) MOJO_OVERRIDE {
35 assert(false); // not reached!
40 SharedData<Router*> router_;
43 // ----------------------------------------------------------------------------
45 Router::HandleIncomingMessageThunk::HandleIncomingMessageThunk(Router* router)
49 Router::HandleIncomingMessageThunk::~HandleIncomingMessageThunk() {
52 bool Router::HandleIncomingMessageThunk::Accept(Message* message) {
53 return router_->HandleIncomingMessage(message);
56 bool Router::HandleIncomingMessageThunk::AcceptWithResponder(
58 MessageReceiver* responder) {
59 assert(false); // not reached!
63 // ----------------------------------------------------------------------------
65 Router::Router(ScopedMessagePipeHandle message_pipe, MojoAsyncWaiter* waiter)
66 : connector_(message_pipe.Pass(), waiter),
68 incoming_receiver_(NULL),
71 connector_.set_incoming_receiver(&thunk_);
75 weak_self_.set_value(NULL);
77 for (ResponderMap::const_iterator i = responders_.begin();
78 i != responders_.end(); ++i) {
83 bool Router::Accept(Message* message) {
84 assert(!message->has_flag(kMessageExpectsResponse));
85 return connector_.Accept(message);
88 bool Router::AcceptWithResponder(Message* message,
89 MessageReceiver* responder) {
90 assert(message->has_flag(kMessageExpectsResponse));
92 // Reserve 0 in case we want it to convey special meaning in the future.
93 uint64_t request_id = next_request_id_++;
95 request_id = next_request_id_++;
97 message->set_request_id(request_id);
98 if (!connector_.Accept(message))
101 // We assume ownership of |responder|.
102 responders_[request_id] = responder;
106 bool Router::HandleIncomingMessage(Message* message) {
107 if (message->has_flag(kMessageExpectsResponse)) {
108 if (incoming_receiver_) {
109 MessageReceiver* responder = new ResponderThunk(weak_self_);
110 bool ok = incoming_receiver_->AcceptWithResponder(message, responder);
116 // If we receive a request expecting a response when the client is not
117 // listening, then we have no choice but to tear down the pipe.
118 connector_.CloseMessagePipe();
119 } else if (message->has_flag(kMessageIsResponse)) {
120 uint64_t request_id = message->request_id();
121 ResponderMap::iterator it = responders_.find(request_id);
122 if (it == responders_.end()) {
126 MessageReceiver* responder = it->second;
127 responders_.erase(it);
128 bool ok = responder->Accept(message);
132 if (incoming_receiver_)
133 return incoming_receiver_->Accept(message);
134 // OK to drop message on the floor.
140 // ----------------------------------------------------------------------------
142 } // namespace internal