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 |