Chromium Code Reviews| 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/debug/stack_trace.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 147 base::AutoLock locker(lock()); | 147 base::AutoLock locker(lock()); |
| 148 CHECK(transferable_); | 148 CHECK(transferable_); |
| 149 calling_init_ = true; | 149 calling_init_ = true; |
| 150 if (channel_) | 150 if (channel_) |
| 151 channel_->Init(this); | 151 channel_->Init(this); |
| 152 calling_init_ = false; | 152 calling_init_ = false; |
| 153 } | 153 } |
| 154 | 154 |
| 155 void MessagePipeDispatcher::CloseOnIO() { | 155 void MessagePipeDispatcher::CloseOnIO() { |
| 156 base::AutoLock locker(lock()); | 156 base::AutoLock locker(lock()); |
| 157 Release(); // To match CloseImplNoLock. | |
| 157 if (transferable_) { | 158 if (transferable_) { |
| 158 if (channel_) { | 159 if (channel_) { |
| 159 channel_->Shutdown(); | 160 channel_->Shutdown(); |
| 160 channel_ = nullptr; | 161 channel_ = nullptr; |
| 161 } | 162 } |
| 162 } else { | 163 } else { |
| 163 if (non_transferable_state_ == CONNECT_CALLED || | 164 if (non_transferable_state_ == CONNECT_CALLED || |
| 164 non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) { | 165 non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) { |
| 165 if (non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) | 166 if (non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) |
| 166 RequestNontransferableChannel(); | 167 RequestNontransferableChannel(); |
| (...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 428 #endif | 429 #endif |
| 429 } | 430 } |
| 430 | 431 |
| 431 void MessagePipeDispatcher::CancelAllAwakablesNoLock() { | 432 void MessagePipeDispatcher::CancelAllAwakablesNoLock() { |
| 432 lock().AssertAcquired(); | 433 lock().AssertAcquired(); |
| 433 awakable_list_.CancelAll(); | 434 awakable_list_.CancelAll(); |
| 434 } | 435 } |
| 435 | 436 |
| 436 void MessagePipeDispatcher::CloseImplNoLock() { | 437 void MessagePipeDispatcher::CloseImplNoLock() { |
| 437 lock().AssertAcquired(); | 438 lock().AssertAcquired(); |
| 439 // We take a manual refcount because at shutdown, the task below might not get | |
| 440 // a chance to execute. If that happens, the RawChannel's will still call our | |
|
msw
2015/12/17 18:49:59
nit: "The RawChannel will" or "The RawChannel's __
jam
2015/12/17 18:54:36
will fix in a followup, thanks
| |
| 441 // OnError method because it always runs (since it watches thread | |
|
msw
2015/12/17 18:49:59
q: Should this try to release in OnError?
jam
2015/12/17 18:54:36
(per in-person discussion)
We could add extra logi
| |
| 442 // destruction). So to avoid UAF, manually add a reference and only release it | |
| 443 // if the task runs. | |
| 444 AddRef(); | |
| 438 internal::g_io_thread_task_runner->PostTask( | 445 internal::g_io_thread_task_runner->PostTask( |
| 439 FROM_HERE, base::Bind(&MessagePipeDispatcher::CloseOnIO, this)); | 446 FROM_HERE, base::Bind(&MessagePipeDispatcher::CloseOnIO, this)); |
| 440 } | 447 } |
| 441 | 448 |
| 442 void MessagePipeDispatcher::SerializeInternal() { | 449 void MessagePipeDispatcher::SerializeInternal() { |
| 443 serialized_ = true; | 450 serialized_ = true; |
| 444 if (!transferable_) { | 451 if (!transferable_) { |
| 445 CHECK(non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) | 452 CHECK(non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) |
| 446 << "Non transferable message pipe being sent after read/write/waited. " | 453 << "Non transferable message pipe being sent after read/write/waited. " |
| 447 << "MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE must be used if " | 454 << "MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE must be used if " |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 990 // PostTask since the broker can call us back synchronously. | 997 // PostTask since the broker can call us back synchronously. |
| 991 internal::g_io_thread_task_runner->PostTask( | 998 internal::g_io_thread_task_runner->PostTask( |
| 992 FROM_HERE, | 999 FROM_HERE, |
| 993 base::Bind(&Broker::ConnectMessagePipe, | 1000 base::Bind(&Broker::ConnectMessagePipe, |
| 994 base::Unretained(internal::g_broker), pipe_id_, | 1001 base::Unretained(internal::g_broker), pipe_id_, |
| 995 base::Unretained(this))); | 1002 base::Unretained(this))); |
| 996 } | 1003 } |
| 997 | 1004 |
| 998 } // namespace edk | 1005 } // namespace edk |
| 999 } // namespace mojo | 1006 } // namespace mojo |
| OLD | NEW |