OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |