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/edk/system/message_pipe.h" | 5 #include "mojo/edk/system/message_pipe.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 | 117 |
118 MessagePipeEndpoint::Type MessagePipe::GetType(unsigned port) { | 118 MessagePipeEndpoint::Type MessagePipe::GetType(unsigned port) { |
119 DCHECK(port == 0 || port == 1); | 119 DCHECK(port == 0 || port == 1); |
120 MutexLocker locker(&mutex_); | 120 MutexLocker locker(&mutex_); |
121 DCHECK(endpoints_[port]); | 121 DCHECK(endpoints_[port]); |
122 | 122 |
123 return endpoints_[port]->GetType(); | 123 return endpoints_[port]->GetType(); |
124 } | 124 } |
125 | 125 |
126 void MessagePipe::CancelAllAwakables(unsigned port) { | 126 void MessagePipe::CancelAllAwakables(unsigned port) { |
127 DCHECK(port == 0 || port == 1); | |
128 | |
129 MutexLocker locker(&mutex_); | 127 MutexLocker locker(&mutex_); |
130 DCHECK(endpoints_[port]); | 128 CancelAllAwakablesNoLock(port); |
131 endpoints_[port]->CancelAllAwakables(); | |
132 } | 129 } |
133 | 130 |
134 void MessagePipe::Close(unsigned port) { | 131 void MessagePipe::Close(unsigned port) { |
135 DCHECK(port == 0 || port == 1); | 132 DCHECK(port == 0 || port == 1); |
136 | 133 |
137 unsigned peer_port = GetPeerPort(port); | 134 unsigned peer_port = GetPeerPort(port); |
138 | 135 |
139 MutexLocker locker(&mutex_); | 136 MutexLocker locker(&mutex_); |
140 // The endpoint's |OnPeerClose()| may have been called first and returned | 137 // The endpoint's |OnPeerClose()| may have been called first and returned |
141 // false, which would have resulted in its destruction. | 138 // false, which would have resulted in its destruction. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 endpoints_[peer_port].reset(); | 276 endpoints_[peer_port].reset(); |
280 } | 277 } |
281 | 278 |
282 endpoints_[port]->Close(); | 279 endpoints_[port]->Close(); |
283 endpoints_[port].reset(replacement_endpoint); | 280 endpoints_[port].reset(replacement_endpoint); |
284 | 281 |
285 *actual_size = channel->GetSerializedEndpointSize(); | 282 *actual_size = channel->GetSerializedEndpointSize(); |
286 return true; | 283 return true; |
287 } | 284 } |
288 | 285 |
| 286 void MessagePipe::CancelAllAwakablesNoLock(unsigned port) { |
| 287 DCHECK(port == 0 || port == 1); |
| 288 mutex_.AssertHeld(); |
| 289 DCHECK(endpoints_[port]); |
| 290 endpoints_[port]->CancelAllAwakables(); |
| 291 } |
| 292 |
289 bool MessagePipe::OnReadMessage(unsigned port, MessageInTransit* message) { | 293 bool MessagePipe::OnReadMessage(unsigned port, MessageInTransit* message) { |
290 MutexLocker locker(&mutex_); | 294 MutexLocker locker(&mutex_); |
291 | 295 |
292 if (!endpoints_[port]) { | 296 if (!endpoints_[port]) { |
293 // This will happen only on the rare occasion that the call to | 297 // This will happen only on the rare occasion that the call to |
294 // |OnReadMessage()| is racing with us calling | 298 // |OnReadMessage()| is racing with us calling |
295 // |ChannelEndpoint::ReplaceClient()|, in which case we reject the message, | 299 // |ChannelEndpoint::ReplaceClient()|, in which case we reject the message, |
296 // and the |ChannelEndpoint| can retry (calling the new client's | 300 // and the |ChannelEndpoint| can retry (calling the new client's |
297 // |OnReadMessage()|). | 301 // |OnReadMessage()|). |
298 return false; | 302 return false; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 endpoints_[port]->EnqueueMessage(std::move(message)); | 352 endpoints_[port]->EnqueueMessage(std::move(message)); |
349 return MOJO_RESULT_OK; | 353 return MOJO_RESULT_OK; |
350 } | 354 } |
351 | 355 |
352 MojoResult MessagePipe::AttachTransportsNoLock( | 356 MojoResult MessagePipe::AttachTransportsNoLock( |
353 unsigned port, | 357 unsigned port, |
354 MessageInTransit* message, | 358 MessageInTransit* message, |
355 std::vector<DispatcherTransport>* transports) { | 359 std::vector<DispatcherTransport>* transports) { |
356 DCHECK(!message->has_dispatchers()); | 360 DCHECK(!message->has_dispatchers()); |
357 | 361 |
358 // You're not allowed to send either handle to a message pipe over the message | |
359 // pipe, so check for this. (The case of trying to write a handle to itself is | |
360 // taken care of by |Core|. That case kind of makes sense, but leads to | |
361 // complications if, e.g., both sides try to do the same thing with their | |
362 // respective handles simultaneously. The other case, of trying to write the | |
363 // peer handle to a handle, doesn't make sense -- since no handle will be | |
364 // available to read the message from.) | |
365 for (size_t i = 0; i < transports->size(); i++) { | |
366 if (!(*transports)[i].is_valid()) | |
367 continue; | |
368 if ((*transports)[i].GetType() == Dispatcher::Type::MESSAGE_PIPE) { | |
369 MessagePipeDispatcherTransport mp_transport((*transports)[i]); | |
370 if (mp_transport.GetMessagePipe() == this) { | |
371 // The other case should have been disallowed by |Core|. (Note: |port| | |
372 // is the peer port of the handle given to |WriteMessage()|.) | |
373 DCHECK_EQ(mp_transport.GetPort(), port); | |
374 return MOJO_RESULT_INVALID_ARGUMENT; | |
375 } | |
376 } | |
377 } | |
378 | |
379 // Clone the dispatchers and attach them to the message. (This must be done as | 362 // Clone the dispatchers and attach them to the message. (This must be done as |
380 // a separate loop, since we want to leave the dispatchers alone on failure.) | 363 // a separate loop, since we want to leave the dispatchers alone on failure.) |
381 std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector()); | 364 std::unique_ptr<DispatcherVector> dispatchers(new DispatcherVector()); |
382 dispatchers->reserve(transports->size()); | 365 dispatchers->reserve(transports->size()); |
383 for (size_t i = 0; i < transports->size(); i++) { | 366 for (size_t i = 0; i < transports->size(); i++) { |
384 if ((*transports)[i].is_valid()) { | 367 if ((*transports)[i].is_valid()) { |
385 dispatchers->push_back( | 368 dispatchers->push_back( |
386 (*transports)[i].CreateEquivalentDispatcherAndClose()); | 369 (*transports)[i].CreateEquivalentDispatcherAndClose(this, port)); |
387 } else { | 370 } else { |
388 LOG(WARNING) << "Enqueueing null dispatcher"; | 371 LOG(WARNING) << "Enqueueing null dispatcher"; |
389 dispatchers->push_back(nullptr); | 372 dispatchers->push_back(nullptr); |
390 } | 373 } |
391 } | 374 } |
392 message->SetDispatchers(std::move(dispatchers)); | 375 message->SetDispatchers(std::move(dispatchers)); |
393 return MOJO_RESULT_OK; | 376 return MOJO_RESULT_OK; |
394 } | 377 } |
395 | 378 |
396 } // namespace system | 379 } // namespace system |
397 } // namespace mojo | 380 } // namespace mojo |
OLD | NEW |