| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | |
| 9 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/location.h" | 12 #include "base/location.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
| 15 #include "mojo/edk/embedder/embedder_internal.h" | 15 #include "mojo/edk/embedder/embedder_internal.h" |
| 16 #include "mojo/edk/system/configuration.h" | 16 #include "mojo/edk/system/configuration.h" |
| 17 #include "mojo/edk/system/message_in_transit.h" | 17 #include "mojo/edk/system/message_in_transit.h" |
| 18 #include "mojo/edk/system/transport_data.h" | 18 #include "mojo/edk/system/transport_data.h" |
| 19 | 19 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 } | 276 } |
| 277 | 277 |
| 278 // Normally, we want to flush any pending writes before shutting down. This | 278 // Normally, we want to flush any pending writes before shutting down. This |
| 279 // doesn't apply when 1) we don't have a handle (for obvious reasons), | 279 // doesn't apply when 1) we don't have a handle (for obvious reasons), |
| 280 // 2) we have a read or write error before (doesn't matter which), or 3) when | 280 // 2) we have a read or write error before (doesn't matter which), or 3) when |
| 281 // there are no pending messages to be written. | 281 // there are no pending messages to be written. |
| 282 if (!IsHandleValid() || error_occurred_ || empty) { | 282 if (!IsHandleValid() || error_occurred_ || empty) { |
| 283 { | 283 { |
| 284 base::AutoLock read_locker(read_lock_); | 284 base::AutoLock read_locker(read_lock_); |
| 285 base::AutoLock locker(write_lock_); | 285 base::AutoLock locker(write_lock_); |
| 286 OnShutdownNoLock(read_buffer_.Pass(), write_buffer_.Pass()); | 286 OnShutdownNoLock(std::move(read_buffer_), std::move(write_buffer_)); |
| 287 } | 287 } |
| 288 | 288 |
| 289 if (initialized_) { | 289 if (initialized_) { |
| 290 base::MessageLoop::current()->RemoveDestructionObserver(this); | 290 base::MessageLoop::current()->RemoveDestructionObserver(this); |
| 291 } | 291 } |
| 292 delete this; | 292 delete this; |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 | 295 |
| 296 base::AutoLock read_locker(read_lock_); | 296 base::AutoLock read_locker(read_lock_); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 | 328 |
| 329 // Reminder: This must be thread-safe. | 329 // Reminder: This must be thread-safe. |
| 330 bool RawChannel::WriteMessage(scoped_ptr<MessageInTransit> message) { | 330 bool RawChannel::WriteMessage(scoped_ptr<MessageInTransit> message) { |
| 331 DCHECK(message); | 331 DCHECK(message); |
| 332 EnsureLazyInitialized(); | 332 EnsureLazyInitialized(); |
| 333 base::AutoLock locker(write_lock_); | 333 base::AutoLock locker(write_lock_); |
| 334 if (write_stopped_) | 334 if (write_stopped_) |
| 335 return false; | 335 return false; |
| 336 | 336 |
| 337 bool queue_was_empty = write_buffer_->message_queue_.IsEmpty(); | 337 bool queue_was_empty = write_buffer_->message_queue_.IsEmpty(); |
| 338 EnqueueMessageNoLock(message.Pass()); | 338 EnqueueMessageNoLock(std::move(message)); |
| 339 if (queue_was_empty && write_ready_) | 339 if (queue_was_empty && write_ready_) |
| 340 return SendQueuedMessagesNoLock(); | 340 return SendQueuedMessagesNoLock(); |
| 341 | 341 |
| 342 return true; | 342 return true; |
| 343 } | 343 } |
| 344 | 344 |
| 345 bool RawChannel::SendQueuedMessagesNoLock() { | 345 bool RawChannel::SendQueuedMessagesNoLock() { |
| 346 DCHECK_EQ(write_buffer_->data_offset_, 0u); | 346 DCHECK_EQ(write_buffer_->data_offset_, 0u); |
| 347 | 347 |
| 348 size_t platform_handles_written = 0; | 348 size_t platform_handles_written = 0; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 | 391 |
| 392 uint32_t offset = 0; | 392 uint32_t offset = 0; |
| 393 while (offset < serialized_write_buffer_size) { | 393 while (offset < serialized_write_buffer_size) { |
| 394 uint32_t message_num_bytes = | 394 uint32_t message_num_bytes = |
| 395 std::min(static_cast<uint32_t>(max_message_num_bytes), | 395 std::min(static_cast<uint32_t>(max_message_num_bytes), |
| 396 static_cast<uint32_t>(serialized_write_buffer_size) - | 396 static_cast<uint32_t>(serialized_write_buffer_size) - |
| 397 offset); | 397 offset); |
| 398 scoped_ptr<MessageInTransit> message(new MessageInTransit( | 398 scoped_ptr<MessageInTransit> message(new MessageInTransit( |
| 399 MessageInTransit::Type::RAW_MESSAGE, message_num_bytes, | 399 MessageInTransit::Type::RAW_MESSAGE, message_num_bytes, |
| 400 static_cast<const char*>(serialized_write_buffer) + offset)); | 400 static_cast<const char*>(serialized_write_buffer) + offset)); |
| 401 write_buffer_->message_queue_.AddMessage(message.Pass()); | 401 write_buffer_->message_queue_.AddMessage(std::move(message)); |
| 402 offset += message_num_bytes; | 402 offset += message_num_bytes; |
| 403 } | 403 } |
| 404 } | 404 } |
| 405 } | 405 } |
| 406 | 406 |
| 407 void RawChannel::OnReadCompletedNoLock(IOResult io_result, size_t bytes_read) { | 407 void RawChannel::OnReadCompletedNoLock(IOResult io_result, size_t bytes_read) { |
| 408 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); | 408 DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); |
| 409 read_lock_.AssertAcquired(); | 409 read_lock_.AssertAcquired(); |
| 410 // Keep reading data in a loop, and dispatch messages if enough data is | 410 // Keep reading data in a loop, and dispatch messages if enough data is |
| 411 // received. Exit the loop if any of the following happens: | 411 // received. Exit the loop if any of the following happens: |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 for (size_t i = 0; i < buffers.size(); ++i) { | 519 for (size_t i = 0; i < buffers.size(); ++i) { |
| 520 buffer->insert(buffer->end(), buffers[i].addr, | 520 buffer->insert(buffer->end(), buffers[i].addr, |
| 521 buffers[i].addr + buffers[i].size); | 521 buffers[i].addr + buffers[i].size); |
| 522 } | 522 } |
| 523 write_buffer_->message_queue_.DiscardMessage(); | 523 write_buffer_->message_queue_.DiscardMessage(); |
| 524 } | 524 } |
| 525 } | 525 } |
| 526 | 526 |
| 527 void RawChannel::EnqueueMessageNoLock(scoped_ptr<MessageInTransit> message) { | 527 void RawChannel::EnqueueMessageNoLock(scoped_ptr<MessageInTransit> message) { |
| 528 write_lock_.AssertAcquired(); | 528 write_lock_.AssertAcquired(); |
| 529 write_buffer_->message_queue_.AddMessage(message.Pass()); | 529 write_buffer_->message_queue_.AddMessage(std::move(message)); |
| 530 } | 530 } |
| 531 | 531 |
| 532 bool RawChannel::OnReadMessageForRawChannel( | 532 bool RawChannel::OnReadMessageForRawChannel( |
| 533 const MessageInTransit::View& message_view) { | 533 const MessageInTransit::View& message_view) { |
| 534 LOG(ERROR) << "Invalid control message (type " << message_view.type() | 534 LOG(ERROR) << "Invalid control message (type " << message_view.type() |
| 535 << ")"; | 535 << ")"; |
| 536 return false; | 536 return false; |
| 537 } | 537 } |
| 538 | 538 |
| 539 RawChannel::Delegate::Error RawChannel::ReadIOResultToError( | 539 RawChannel::Delegate::Error RawChannel::ReadIOResultToError( |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 } else { | 653 } else { |
| 654 ScopedPlatformHandleVectorPtr platform_handles; | 654 ScopedPlatformHandleVectorPtr platform_handles; |
| 655 if (message_view.transport_data_buffer()) { | 655 if (message_view.transport_data_buffer()) { |
| 656 size_t num_platform_handles; | 656 size_t num_platform_handles; |
| 657 const void* platform_handle_table; | 657 const void* platform_handle_table; |
| 658 TransportData::GetPlatformHandleTable( | 658 TransportData::GetPlatformHandleTable( |
| 659 message_view.transport_data_buffer(), &num_platform_handles, | 659 message_view.transport_data_buffer(), &num_platform_handles, |
| 660 &platform_handle_table); | 660 &platform_handle_table); |
| 661 | 661 |
| 662 if (num_platform_handles > 0) { | 662 if (num_platform_handles > 0) { |
| 663 platform_handles = | 663 platform_handles = GetReadPlatformHandles(num_platform_handles, |
| 664 GetReadPlatformHandles(num_platform_handles, | 664 platform_handle_table); |
| 665 platform_handle_table).Pass(); | |
| 666 if (!platform_handles) { | 665 if (!platform_handles) { |
| 667 LOG(ERROR) << "Invalid number of platform handles received"; | 666 LOG(ERROR) << "Invalid number of platform handles received"; |
| 668 CallOnError(Delegate::ERROR_READ_BAD_MESSAGE); | 667 CallOnError(Delegate::ERROR_READ_BAD_MESSAGE); |
| 669 *stop_dispatching = true; | 668 *stop_dispatching = true; |
| 670 return; // |this| may have been destroyed in |CallOnError()|. | 669 return; // |this| may have been destroyed in |CallOnError()|. |
| 671 } | 670 } |
| 672 } | 671 } |
| 673 } | 672 } |
| 674 | 673 |
| 675 // TODO(vtl): In the case that we aren't expecting any platform handles, | 674 // TODO(vtl): In the case that we aren't expecting any platform handles, |
| 676 // for the POSIX implementation, we should confirm that none are stored. | 675 // for the POSIX implementation, we should confirm that none are stored. |
| 677 if (delegate_) { | 676 if (delegate_) { |
| 678 DCHECK(!calling_delegate_); | 677 DCHECK(!calling_delegate_); |
| 679 calling_delegate_ = true; | 678 calling_delegate_ = true; |
| 680 delegate_->OnReadMessage(message_view, platform_handles.Pass()); | 679 delegate_->OnReadMessage(message_view, std::move(platform_handles)); |
| 681 calling_delegate_ = false; | 680 calling_delegate_ = false; |
| 682 } | 681 } |
| 683 } | 682 } |
| 684 | 683 |
| 685 *did_dispatch_message = true; | 684 *did_dispatch_message = true; |
| 686 | 685 |
| 687 // Update our state. | 686 // Update our state. |
| 688 read_buffer_start += message_size; | 687 read_buffer_start += message_size; |
| 689 remaining_bytes -= message_size; | 688 remaining_bytes -= message_size; |
| 690 } | 689 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 720 OnReadCompletedNoLock(io_result, bytes_read); | 719 OnReadCompletedNoLock(io_result, bytes_read); |
| 721 } | 720 } |
| 722 | 721 |
| 723 void RawChannel::WillDestroyCurrentMessageLoop() { | 722 void RawChannel::WillDestroyCurrentMessageLoop() { |
| 724 base::AutoLock locker(read_lock_); | 723 base::AutoLock locker(read_lock_); |
| 725 OnReadCompletedNoLock(IO_FAILED_SHUTDOWN, 0); | 724 OnReadCompletedNoLock(IO_FAILED_SHUTDOWN, 0); |
| 726 } | 725 } |
| 727 | 726 |
| 728 } // namespace edk | 727 } // namespace edk |
| 729 } // namespace mojo | 728 } // namespace mojo |
| OLD | NEW |