OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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_dispatcher.h" | 5 #include "mojo/edk/system/message_pipe_dispatcher.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/stack_trace.h" |
8 #include "base/logging.h" | 9 #include "base/logging.h" |
9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
10 #include "mojo/edk/embedder/embedder_internal.h" | 11 #include "mojo/edk/embedder/embedder_internal.h" |
11 #include "mojo/edk/embedder/platform_handle_utils.h" | 12 #include "mojo/edk/embedder/platform_handle_utils.h" |
12 #include "mojo/edk/embedder/platform_shared_buffer.h" | 13 #include "mojo/edk/embedder/platform_shared_buffer.h" |
13 #include "mojo/edk/embedder/platform_support.h" | 14 #include "mojo/edk/embedder/platform_support.h" |
14 #include "mojo/edk/system/broker.h" | 15 #include "mojo/edk/system/broker.h" |
15 #include "mojo/edk/system/configuration.h" | 16 #include "mojo/edk/system/configuration.h" |
16 #include "mojo/edk/system/message_in_transit.h" | 17 #include "mojo/edk/system/message_in_transit.h" |
17 #include "mojo/edk/system/options_validation.h" | 18 #include "mojo/edk/system/options_validation.h" |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 void MessagePipeDispatcher::CloseImplNoLock() { | 435 void MessagePipeDispatcher::CloseImplNoLock() { |
435 lock().AssertAcquired(); | 436 lock().AssertAcquired(); |
436 internal::g_io_thread_task_runner->PostTask( | 437 internal::g_io_thread_task_runner->PostTask( |
437 FROM_HERE, base::Bind(&MessagePipeDispatcher::CloseOnIO, this)); | 438 FROM_HERE, base::Bind(&MessagePipeDispatcher::CloseOnIO, this)); |
438 } | 439 } |
439 | 440 |
440 void MessagePipeDispatcher::SerializeInternal() { | 441 void MessagePipeDispatcher::SerializeInternal() { |
441 serialized_ = true; | 442 serialized_ = true; |
442 if (!transferable_) { | 443 if (!transferable_) { |
443 CHECK(non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) | 444 CHECK(non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) |
444 << "Non transferable message pipe being sent after read/write. " | 445 << "Non transferable message pipe being sent after read/write/waited. " |
445 << "MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE must be used if " | 446 << "MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE must be used if " |
446 << "the pipe can be sent after it's read or written."; | 447 << "the pipe can be sent after it's read or written. This message pipe " |
| 448 << "was previously bound at:\n" |
| 449 << non_transferable_bound_stack_->ToString(); |
| 450 |
447 non_transferable_state_ = SERIALISED; | 451 non_transferable_state_ = SERIALISED; |
448 return; | 452 return; |
449 } | 453 } |
450 | 454 |
451 // We need to stop watching handle immediately, even though not on IO thread, | 455 // We need to stop watching handle immediately, even though not on IO thread, |
452 // so that other messages aren't read after this. | 456 // so that other messages aren't read after this. |
453 std::vector<int> serialized_read_fds, serialized_write_fds; | 457 std::vector<int> serialized_read_fds, serialized_write_fds; |
454 if (channel_) { | 458 if (channel_) { |
455 bool write_error = false; | 459 bool write_error = false; |
456 | 460 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( | 608 MojoResult MessagePipeDispatcher::ReadMessageImplNoLock( |
605 void* bytes, | 609 void* bytes, |
606 uint32_t* num_bytes, | 610 uint32_t* num_bytes, |
607 DispatcherVector* dispatchers, | 611 DispatcherVector* dispatchers, |
608 uint32_t* num_dispatchers, | 612 uint32_t* num_dispatchers, |
609 MojoReadMessageFlags flags) { | 613 MojoReadMessageFlags flags) { |
610 lock().AssertAcquired(); | 614 lock().AssertAcquired(); |
611 if (channel_) { | 615 if (channel_) { |
612 channel_->EnsureLazyInitialized(); | 616 channel_->EnsureLazyInitialized(); |
613 } else if (!transferable_) { | 617 } else if (!transferable_) { |
614 if (non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) { | 618 if (non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) { |
615 RequestNontransferableChannel(); | 619 RequestNontransferableChannel(); |
616 return MOJO_RESULT_SHOULD_WAIT; | 620 return MOJO_RESULT_SHOULD_WAIT; |
617 } else if (non_transferable_state_ == CONNECT_CALLED) { | 621 } else if (non_transferable_state_ == CONNECT_CALLED) { |
618 return MOJO_RESULT_SHOULD_WAIT; | 622 return MOJO_RESULT_SHOULD_WAIT; |
619 } | 623 } |
620 } | 624 } |
621 | 625 |
622 DCHECK(!dispatchers || dispatchers->empty()); | 626 DCHECK(!dispatchers || dispatchers->empty()); |
623 | 627 |
624 const uint32_t max_bytes = !num_bytes ? 0 : *num_bytes; | 628 const uint32_t max_bytes = !num_bytes ? 0 : *num_bytes; |
625 const uint32_t max_num_dispatchers = num_dispatchers ? *num_dispatchers : 0; | 629 const uint32_t max_num_dispatchers = num_dispatchers ? *num_dispatchers : 0; |
626 | 630 |
627 if (message_queue_.IsEmpty()) | 631 if (message_queue_.IsEmpty()) |
628 return channel_ ? MOJO_RESULT_SHOULD_WAIT : MOJO_RESULT_FAILED_PRECONDITION; | 632 return channel_ ? MOJO_RESULT_SHOULD_WAIT : MOJO_RESULT_FAILED_PRECONDITION; |
629 | 633 |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 } | 980 } |
977 message->SetDispatchers(dispatchers.Pass()); | 981 message->SetDispatchers(dispatchers.Pass()); |
978 return MOJO_RESULT_OK; | 982 return MOJO_RESULT_OK; |
979 } | 983 } |
980 | 984 |
981 void MessagePipeDispatcher::RequestNontransferableChannel() { | 985 void MessagePipeDispatcher::RequestNontransferableChannel() { |
982 lock().AssertAcquired(); | 986 lock().AssertAcquired(); |
983 CHECK(!transferable_); | 987 CHECK(!transferable_); |
984 CHECK_EQ(non_transferable_state_, WAITING_FOR_READ_OR_WRITE); | 988 CHECK_EQ(non_transferable_state_, WAITING_FOR_READ_OR_WRITE); |
985 non_transferable_state_ = CONNECT_CALLED; | 989 non_transferable_state_ = CONNECT_CALLED; |
| 990 #if !defined(OFFICIAL_BUILD) |
| 991 non_transferable_bound_stack_.reset(new base::debug::StackTrace); |
| 992 #endif |
986 | 993 |
987 // PostTask since the broker can call us back synchronously. | 994 // PostTask since the broker can call us back synchronously. |
988 internal::g_io_thread_task_runner->PostTask( | 995 internal::g_io_thread_task_runner->PostTask( |
989 FROM_HERE, | 996 FROM_HERE, |
990 base::Bind(&Broker::ConnectMessagePipe, | 997 base::Bind(&Broker::ConnectMessagePipe, |
991 base::Unretained(internal::g_broker), pipe_id_, | 998 base::Unretained(internal::g_broker), pipe_id_, |
992 base::Unretained(this))); | 999 base::Unretained(this))); |
993 } | 1000 } |
994 | 1001 |
995 } // namespace edk | 1002 } // namespace edk |
996 } // namespace mojo | 1003 } // namespace mojo |
OLD | NEW |