| 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 |