| 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/system/channel.h" | 5 #include "mojo/system/channel.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
| 14 #include "mojo/system/message_pipe_endpoint.h" | 14 #include "mojo/system/message_pipe_endpoint.h" |
| 15 #include "mojo/system/transport_data.h" |
| 15 | 16 |
| 16 namespace mojo { | 17 namespace mojo { |
| 17 namespace system { | 18 namespace system { |
| 18 | 19 |
| 19 COMPILE_ASSERT(Channel::kBootstrapEndpointId != | 20 COMPILE_ASSERT(Channel::kBootstrapEndpointId != |
| 20 MessageInTransit::kInvalidEndpointId, | 21 MessageInTransit::kInvalidEndpointId, |
| 21 kBootstrapEndpointId_is_invalid); | 22 kBootstrapEndpointId_is_invalid); |
| 22 | 23 |
| 23 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId | 24 STATIC_CONST_MEMBER_DEFINITION const MessageInTransit::EndpointId |
| 24 Channel::kBootstrapEndpointId; | 25 Channel::kBootstrapEndpointId; |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 endpoint_info = it->second; | 341 endpoint_info = it->second; |
| 341 } | 342 } |
| 342 | 343 |
| 343 // Ignore messages for zombie endpoints (not an error). | 344 // Ignore messages for zombie endpoints (not an error). |
| 344 if (endpoint_info.state != EndpointInfo::STATE_NORMAL) { | 345 if (endpoint_info.state != EndpointInfo::STATE_NORMAL) { |
| 345 DVLOG(2) << "Ignoring downstream message for zombie endpoint (local ID = " | 346 DVLOG(2) << "Ignoring downstream message for zombie endpoint (local ID = " |
| 346 << local_id << ", remote ID = " << message_view.source_id() << ")"; | 347 << local_id << ", remote ID = " << message_view.source_id() << ")"; |
| 347 return; | 348 return; |
| 348 } | 349 } |
| 349 | 350 |
| 350 // We need to duplicate the message, because |EnqueueMessage()| will take | 351 // We need to duplicate the message (data), because |EnqueueMessage()| will |
| 351 // ownership of it. | 352 // take ownership of it. |
| 352 scoped_ptr<MessageInTransit> message(new MessageInTransit(message_view)); | 353 scoped_ptr<MessageInTransit> message(new MessageInTransit(message_view)); |
| 353 message->DeserializeDispatchers(this); | 354 if (message_view.transport_data_buffer_size() > 0) { |
| 355 DCHECK(message_view.transport_data_buffer()); |
| 356 message->SetDispatchers( |
| 357 TransportData::DeserializeDispatchersFromBuffer( |
| 358 message_view.transport_data_buffer(), |
| 359 message_view.transport_data_buffer_size(), |
| 360 this)); |
| 361 } |
| 354 MojoResult result = endpoint_info.message_pipe->EnqueueMessage( | 362 MojoResult result = endpoint_info.message_pipe->EnqueueMessage( |
| 355 MessagePipe::GetPeerPort(endpoint_info.port), message.Pass()); | 363 MessagePipe::GetPeerPort(endpoint_info.port), message.Pass()); |
| 356 if (result != MOJO_RESULT_OK) { | 364 if (result != MOJO_RESULT_OK) { |
| 357 // TODO(vtl): This might be a "non-error", e.g., if the destination endpoint | 365 // TODO(vtl): This might be a "non-error", e.g., if the destination endpoint |
| 358 // has been closed (in an unavoidable race). This might also be a "remote" | 366 // has been closed (in an unavoidable race). This might also be a "remote" |
| 359 // error, e.g., if the remote side is sending invalid control messages (to | 367 // error, e.g., if the remote side is sending invalid control messages (to |
| 360 // the message pipe). | 368 // the message pipe). |
| 361 HandleLocalError(base::StringPrintf( | 369 HandleLocalError(base::StringPrintf( |
| 362 "Failed to enqueue message to local ID %u (result %d)", | 370 "Failed to enqueue message to local ID %u (result %d)", |
| 363 static_cast<unsigned>(local_id), static_cast<int>(result))); | 371 static_cast<unsigned>(local_id), static_cast<int>(result))); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 459 |
| 452 return true; | 460 return true; |
| 453 } | 461 } |
| 454 | 462 |
| 455 bool Channel::SendControlMessage(MessageInTransit::Subtype subtype, | 463 bool Channel::SendControlMessage(MessageInTransit::Subtype subtype, |
| 456 MessageInTransit::EndpointId local_id, | 464 MessageInTransit::EndpointId local_id, |
| 457 MessageInTransit::EndpointId remote_id) { | 465 MessageInTransit::EndpointId remote_id) { |
| 458 DVLOG(2) << "Sending channel control message: subtype " << subtype | 466 DVLOG(2) << "Sending channel control message: subtype " << subtype |
| 459 << ", local ID " << local_id << ", remote ID " << remote_id; | 467 << ", local ID " << local_id << ", remote ID " << remote_id; |
| 460 scoped_ptr<MessageInTransit> message(new MessageInTransit( | 468 scoped_ptr<MessageInTransit> message(new MessageInTransit( |
| 461 MessageInTransit::kTypeChannel, subtype, 0, 0, NULL)); | 469 MessageInTransit::kTypeChannel, subtype, 0, NULL)); |
| 462 message->set_source_id(local_id); | 470 message->set_source_id(local_id); |
| 463 message->set_destination_id(remote_id); | 471 message->set_destination_id(remote_id); |
| 464 return WriteMessage(message.Pass()); | 472 return WriteMessage(message.Pass()); |
| 465 } | 473 } |
| 466 | 474 |
| 467 void Channel::HandleRemoteError(const base::StringPiece& error_message) { | 475 void Channel::HandleRemoteError(const base::StringPiece& error_message) { |
| 468 // TODO(vtl): Is this how we really want to handle this? Probably we want to | 476 // TODO(vtl): Is this how we really want to handle this? Probably we want to |
| 469 // terminate the connection, since it's spewing invalid stuff. | 477 // terminate the connection, since it's spewing invalid stuff. |
| 470 LOG(WARNING) << error_message; | 478 LOG(WARNING) << error_message; |
| 471 } | 479 } |
| 472 | 480 |
| 473 void Channel::HandleLocalError(const base::StringPiece& error_message) { | 481 void Channel::HandleLocalError(const base::StringPiece& error_message) { |
| 474 // TODO(vtl): Is this how we really want to handle this? | 482 // TODO(vtl): Is this how we really want to handle this? |
| 475 // Sometimes we'll want to propagate the error back to the message pipe | 483 // Sometimes we'll want to propagate the error back to the message pipe |
| 476 // (endpoint), and notify it that the remote is (effectively) closed. | 484 // (endpoint), and notify it that the remote is (effectively) closed. |
| 477 // Sometimes we'll want to kill the channel (and notify all the endpoints that | 485 // Sometimes we'll want to kill the channel (and notify all the endpoints that |
| 478 // their remotes are dead. | 486 // their remotes are dead. |
| 479 LOG(WARNING) << error_message; | 487 LOG(WARNING) << error_message; |
| 480 } | 488 } |
| 481 | 489 |
| 482 } // namespace system | 490 } // namespace system |
| 483 } // namespace mojo | 491 } // namespace mojo |
| OLD | NEW |