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

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

Issue 2250183003: Make the fuchsia mojo/public repo the source of truth. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 4 years, 4 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 | « mojo/public/cpp/bindings/lib/router.h ('k') | mojo/public/cpp/bindings/lib/shared_data.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 <string>
8 #include <utility>
9
10 #include "mojo/public/cpp/bindings/message_validator.h"
11 #include "mojo/public/cpp/environment/logging.h"
12
13 namespace mojo {
14 namespace internal {
15
16 // ----------------------------------------------------------------------------
17
18 class ResponderThunk : public MessageReceiverWithStatus {
19 public:
20 explicit ResponderThunk(const SharedData<Router*>& router)
21 : router_(router), accept_was_invoked_(false) {}
22 ~ResponderThunk() override {
23 if (!accept_was_invoked_) {
24 // The Mojo application handled a message that was expecting a response
25 // but did not send a response.
26 Router* router = router_.value();
27 if (router) {
28 // We close the pipe here as a way of signaling to the calling
29 // application that an error condition occurred. Without this the
30 // calling application would have no way of knowing it should stop
31 // waiting for a response.
32 router->CloseMessagePipe();
33 }
34 }
35 }
36
37 // MessageReceiver implementation:
38 bool Accept(Message* message) override {
39 accept_was_invoked_ = true;
40 MOJO_DCHECK(message->has_flag(kMessageIsResponse));
41
42 bool result = false;
43
44 Router* router = router_.value();
45 if (router)
46 result = router->Accept(message);
47
48 return result;
49 }
50
51 // MessageReceiverWithStatus implementation:
52 bool IsValid() override {
53 Router* router = router_.value();
54 return router && !router->encountered_error() && router->is_valid();
55 }
56
57 private:
58 SharedData<Router*> router_;
59 bool accept_was_invoked_;
60 };
61
62 // ----------------------------------------------------------------------------
63
64 Router::HandleIncomingMessageThunk::HandleIncomingMessageThunk(Router* router)
65 : router_(router) {}
66
67 Router::HandleIncomingMessageThunk::~HandleIncomingMessageThunk() {}
68
69 bool Router::HandleIncomingMessageThunk::Accept(Message* message) {
70 return router_->HandleIncomingMessage(message);
71 }
72
73 // ----------------------------------------------------------------------------
74
75 Router::Router(ScopedMessagePipeHandle message_pipe,
76 MessageValidatorList validators,
77 const MojoAsyncWaiter* waiter)
78 : thunk_(this),
79 validators_(std::move(validators)),
80 connector_(message_pipe.Pass(), waiter),
81 weak_self_(this),
82 incoming_receiver_(nullptr),
83 next_request_id_(0),
84 testing_mode_(false) {
85 // This receiver thunk redirects to Router::HandleIncomingMessage.
86 connector_.set_incoming_receiver(&thunk_);
87 }
88
89 Router::~Router() {
90 weak_self_.set_value(nullptr);
91
92 for (ResponderMap::const_iterator i = responders_.begin();
93 i != responders_.end();
94 ++i) {
95 delete i->second;
96 }
97 }
98
99 bool Router::Accept(Message* message) {
100 MOJO_DCHECK(!message->has_flag(kMessageExpectsResponse));
101 return connector_.Accept(message);
102 }
103
104 bool Router::AcceptWithResponder(Message* message, MessageReceiver* responder) {
105 MOJO_DCHECK(message->has_flag(kMessageExpectsResponse));
106
107 // Reserve 0 in case we want it to convey special meaning in the future.
108 uint64_t request_id = next_request_id_++;
109 if (request_id == 0)
110 request_id = next_request_id_++;
111
112 message->set_request_id(request_id);
113 if (!connector_.Accept(message))
114 return false;
115
116 // We assume ownership of |responder|.
117 responders_[request_id] = responder;
118 return true;
119 }
120
121 void Router::EnableTestingMode() {
122 testing_mode_ = true;
123 connector_.set_enforce_errors_from_incoming_receiver(false);
124 }
125
126 bool Router::HandleIncomingMessage(Message* message) {
127 std::string* err = nullptr;
128 #ifndef NDEBUG
129 std::string err2;
130 err = &err2;
131 #endif
132
133 ValidationError result = RunValidatorsOnMessage(validators_, message, err);
134 if (result != ValidationError::NONE)
135 return false;
136
137 if (message->has_flag(kMessageExpectsResponse)) {
138 if (incoming_receiver_) {
139 MessageReceiverWithStatus* responder = new ResponderThunk(weak_self_);
140 bool ok = incoming_receiver_->AcceptWithResponder(message, responder);
141 if (!ok)
142 delete responder;
143 return ok;
144 }
145
146 // If we receive a request expecting a response when the client is not
147 // listening, then we have no choice but to tear down the pipe.
148 connector_.CloseMessagePipe();
149 } else if (message->has_flag(kMessageIsResponse)) {
150 uint64_t request_id = message->request_id();
151 ResponderMap::iterator it = responders_.find(request_id);
152 if (it == responders_.end()) {
153 MOJO_DCHECK(testing_mode_);
154 return false;
155 }
156 MessageReceiver* responder = it->second;
157 responders_.erase(it);
158 bool ok = responder->Accept(message);
159 delete responder;
160 return ok;
161 } else {
162 if (incoming_receiver_)
163 return incoming_receiver_->Accept(message);
164 // OK to drop message on the floor.
165 }
166
167 return false;
168 }
169
170 // ----------------------------------------------------------------------------
171
172 } // namespace internal
173 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/router.h ('k') | mojo/public/cpp/bindings/lib/shared_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698