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

Side by Side Diff: mojo/public/cpp/bindings/lib/connector.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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/connector.h" 5 #include "mojo/public/cpp/bindings/lib/connector.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 } 80 }
81 81
82 ScopedMessagePipeHandle Connector::PassMessagePipe() { 82 ScopedMessagePipeHandle Connector::PassMessagePipe() {
83 DCHECK(thread_checker_.CalledOnValidThread()); 83 DCHECK(thread_checker_.CalledOnValidThread());
84 84
85 CancelWait(); 85 CancelWait();
86 MayAutoLock locker(lock_.get()); 86 MayAutoLock locker(lock_.get());
87 return std::move(message_pipe_); 87 return std::move(message_pipe_);
88 } 88 }
89 89
90 void Connector::RaiseError() { 90 void Connector::RaiseError(Result error) {
91 DCHECK(thread_checker_.CalledOnValidThread()); 91 DCHECK(thread_checker_.CalledOnValidThread());
92 DCHECK(!error.Succeeded());
93
94 // If this was a message validation error, notify the system of a bad message.
95 if (error.type() == Result::Type::BAD_MESSAGE)
96 error.message().NotifyBadMessage(error.details());
92 97
93 HandleError(true, true); 98 HandleError(true, true);
94 } 99 }
95 100
96 bool Connector::WaitForIncomingMessage(MojoDeadline deadline) { 101 bool Connector::WaitForIncomingMessage(MojoDeadline deadline) {
97 DCHECK(thread_checker_.CalledOnValidThread()); 102 DCHECK(thread_checker_.CalledOnValidThread());
98 103
99 if (error_) 104 if (error_)
100 return false; 105 return false;
101 106
(...skipping 26 matching lines...) Expand all
128 void Connector::ResumeIncomingMethodCallProcessing() { 133 void Connector::ResumeIncomingMethodCallProcessing() {
129 DCHECK(thread_checker_.CalledOnValidThread()); 134 DCHECK(thread_checker_.CalledOnValidThread());
130 135
131 if (!paused_) 136 if (!paused_)
132 return; 137 return;
133 138
134 paused_ = false; 139 paused_ = false;
135 WaitToReadMore(); 140 WaitToReadMore();
136 } 141 }
137 142
138 bool Connector::Accept(Message* message) { 143 MessageReceiver::Result Connector::Accept(Message* message) {
139 DCHECK(lock_ || thread_checker_.CalledOnValidThread()); 144 DCHECK(lock_ || thread_checker_.CalledOnValidThread());
140 145
141 // It shouldn't hurt even if |error_| may be changed by a different thread at 146 // It shouldn't hurt even if |error_| may be changed by a different thread at
142 // the same time. The outcome is that we may write into |message_pipe_| after 147 // the same time. The outcome is that we may write into |message_pipe_| after
143 // encountering an error, which should be fine. 148 // encountering an error, which should be fine.
144 if (error_) 149 if (error_)
145 return false; 150 return Result(Result::Type::SEND_FAILED);
146 151
147 MayAutoLock locker(lock_.get()); 152 MayAutoLock locker(lock_.get());
148 153
149 if (!message_pipe_.is_valid() || drop_writes_) 154 if (!message_pipe_.is_valid() || drop_writes_)
150 return true; 155 return Result::ForSuccess();
151 156
152 MojoResult rv = 157 MojoResult rv =
153 WriteMessageNew(message_pipe_.get(), message->TakeMojoMessage(), 158 WriteMessageNew(message_pipe_.get(), message->TakeMojoMessage(),
154 MOJO_WRITE_MESSAGE_FLAG_NONE); 159 MOJO_WRITE_MESSAGE_FLAG_NONE);
155 160
156 switch (rv) { 161 switch (rv) {
157 case MOJO_RESULT_OK: 162 case MOJO_RESULT_OK:
158 break; 163 break;
159 case MOJO_RESULT_FAILED_PRECONDITION: 164 case MOJO_RESULT_FAILED_PRECONDITION:
160 // There's no point in continuing to write to this pipe since the other 165 // There's no point in continuing to write to this pipe since the other
161 // end is gone. Avoid writing any future messages. Hide write failures 166 // end is gone. Avoid writing any future messages. Hide write failures
162 // from the caller since we'd like them to continue consuming any backlog 167 // from the caller since we'd like them to continue consuming any backlog
163 // of incoming messages before regarding the message pipe as closed. 168 // of incoming messages before regarding the message pipe as closed.
164 drop_writes_ = true; 169 drop_writes_ = true;
165 break; 170 break;
166 case MOJO_RESULT_BUSY: 171 case MOJO_RESULT_BUSY:
167 // We'd get a "busy" result if one of the message's handles is: 172 // We'd get a "busy" result if one of the message's handles is:
168 // - |message_pipe_|'s own handle; 173 // - |message_pipe_|'s own handle;
169 // - simultaneously being used on another thread; or 174 // - simultaneously being used on another thread; or
170 // - in a "busy" state that prohibits it from being transferred (e.g., 175 // - in a "busy" state that prohibits it from being transferred (e.g.,
171 // a data pipe handle in the middle of a two-phase read/write, 176 // a data pipe handle in the middle of a two-phase read/write,
172 // regardless of which thread that two-phase read/write is happening 177 // regardless of which thread that two-phase read/write is happening
173 // on). 178 // on).
174 // TODO(vtl): I wonder if this should be a |DCHECK()|. (But, until 179 // TODO(vtl): I wonder if this should be a |DCHECK()|. (But, until
175 // crbug.com/389666, etc. are resolved, this will make tests fail quickly 180 // crbug.com/389666, etc. are resolved, this will make tests fail quickly
176 // rather than hanging.) 181 // rather than hanging.)
177 CHECK(false) << "Race condition or other bug detected"; 182 CHECK(false) << "Race condition or other bug detected";
178 return false; 183 return Result(Result::Type::SEND_FAILED);
179 default: 184 default:
180 // This particular write was rejected, presumably because of bad input. 185 // This particular write was rejected, presumably because of bad input.
181 // The pipe is not necessarily in a bad state. 186 // The pipe is not necessarily in a bad state.
182 return false; 187 return Result(Result::Type::SEND_FAILED);
183 } 188 }
184 return true; 189 return Result::ForSuccess();
185 } 190 }
186 191
187 void Connector::AllowWokenUpBySyncWatchOnSameThread() { 192 void Connector::AllowWokenUpBySyncWatchOnSameThread() {
188 DCHECK(thread_checker_.CalledOnValidThread()); 193 DCHECK(thread_checker_.CalledOnValidThread());
189 194
190 allow_woken_up_by_others_ = true; 195 allow_woken_up_by_others_ = true;
191 196
192 EnsureSyncWatcherExists(); 197 EnsureSyncWatcherExists();
193 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); 198 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread();
194 } 199 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
249 254
250 if (allow_woken_up_by_others_) { 255 if (allow_woken_up_by_others_) {
251 EnsureSyncWatcherExists(); 256 EnsureSyncWatcherExists();
252 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread(); 257 sync_watcher_->AllowWokenUpBySyncWatchOnSameThread();
253 } 258 }
254 } 259 }
255 260
256 bool Connector::ReadSingleMessage(MojoResult* read_result) { 261 bool Connector::ReadSingleMessage(MojoResult* read_result) {
257 CHECK(!paused_); 262 CHECK(!paused_);
258 263
259 bool receiver_result = false; 264 bool received_message = false;
260 265
261 // Detect if |this| was destroyed during message dispatch. Allow for the 266 // Detect if |this| was destroyed during message dispatch. Allow for the
262 // possibility of re-entering ReadMore() through message dispatch. 267 // possibility of re-entering ReadMore() through message dispatch.
263 base::WeakPtr<Connector> weak_self = weak_self_; 268 base::WeakPtr<Connector> weak_self = weak_self_;
264 269
265 Message message; 270 Message message;
266 const MojoResult rv = ReadMessage(message_pipe_.get(), &message); 271 const MojoResult rv = ReadMessage(message_pipe_.get(), &message);
267 *read_result = rv; 272 *read_result = rv;
268 273
269 if (rv == MOJO_RESULT_OK) { 274 if (rv == MOJO_RESULT_OK && incoming_receiver_) {
270 receiver_result = 275 Result result = incoming_receiver_->Accept(&message);
271 incoming_receiver_ && incoming_receiver_->Accept(&message); 276 if (result.type() == Result::Type::BAD_MESSAGE)
277 result.message().NotifyBadMessage(result.details());
278 received_message = result.Succeeded();
272 } 279 }
273 280
274 if (!weak_self) 281 if (!weak_self)
275 return false; 282 return false;
276 283
277 if (rv == MOJO_RESULT_SHOULD_WAIT) 284 if (rv == MOJO_RESULT_SHOULD_WAIT)
278 return true; 285 return true;
279 286
280 if (rv != MOJO_RESULT_OK) { 287 if (rv != MOJO_RESULT_OK) {
281 HandleError(rv != MOJO_RESULT_FAILED_PRECONDITION, false); 288 HandleError(rv != MOJO_RESULT_FAILED_PRECONDITION, false);
282 return false; 289 return false;
283 } 290 }
284 291
285 if (enforce_errors_from_incoming_receiver_ && !receiver_result) { 292 if (enforce_errors_from_incoming_receiver_ && !received_message) {
286 HandleError(true, false); 293 HandleError(true, false);
287 return false; 294 return false;
288 } 295 }
289 return true; 296 return true;
290 } 297 }
291 298
292 void Connector::ReadAllAvailableMessages() { 299 void Connector::ReadAllAvailableMessages() {
293 while (!error_) { 300 while (!error_) {
294 MojoResult rv; 301 MojoResult rv;
295 302
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 if (sync_watcher_) 354 if (sync_watcher_)
348 return; 355 return;
349 sync_watcher_.reset(new SyncHandleWatcher( 356 sync_watcher_.reset(new SyncHandleWatcher(
350 message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE, 357 message_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE,
351 base::Bind(&Connector::OnSyncHandleWatcherHandleReady, 358 base::Bind(&Connector::OnSyncHandleWatcherHandleReady,
352 base::Unretained(this)))); 359 base::Unretained(this))));
353 } 360 }
354 361
355 } // namespace internal 362 } // namespace internal
356 } // namespace mojo 363 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698