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 <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <limits> | 10 #include <limits> |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 // posted task. | 463 // posted task. |
464 if (!transferable_ && non_transferable_state_ == CLOSED) | 464 if (!transferable_ && non_transferable_state_ == CLOSED) |
465 return; | 465 return; |
466 | 466 |
467 // We take a manual refcount because at shutdown, the task below might not get | 467 // We take a manual refcount because at shutdown, the task below might not get |
468 // a chance to execute. If that happens, the RawChannel will still call our | 468 // a chance to execute. If that happens, the RawChannel will still call our |
469 // OnError method because it always runs (since it watches thread | 469 // OnError method because it always runs (since it watches thread |
470 // destruction). So to avoid UAF, manually add a reference and only release it | 470 // destruction). So to avoid UAF, manually add a reference and only release it |
471 // if the task runs. | 471 // if the task runs. |
472 AddRef(); | 472 AddRef(); |
473 internal::g_io_thread_task_runner->PostTask( | 473 if (!internal::g_io_thread_task_runner->PostTask( |
474 FROM_HERE, base::Bind(&MessagePipeDispatcher::CloseOnIOAndRelease, this)); | 474 FROM_HERE, |
| 475 base::Bind(&MessagePipeDispatcher::CloseOnIOAndRelease, this))) { |
| 476 // Avoid a shutdown leak in unittests. If the thread is shutting down, |
| 477 // we can't connect to the other end to let it know that we're closed either |
| 478 // way. |
| 479 if (!transferable_ && non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) |
| 480 Release(); |
| 481 } |
475 } | 482 } |
476 | 483 |
477 void MessagePipeDispatcher::SerializeInternal() { | 484 void MessagePipeDispatcher::SerializeInternal() { |
478 serialized_ = true; | 485 serialized_ = true; |
479 if (!transferable_) { | 486 if (!transferable_) { |
480 CHECK(non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) | 487 CHECK(non_transferable_state_ == WAITING_FOR_READ_OR_WRITE) |
481 << "Non transferable message pipe being sent after read/write/waited. " | 488 << "Non transferable message pipe being sent after read/write/waited. " |
482 << "MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE must be used if " | 489 << "MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE must be used if " |
483 << "the pipe can be sent after it's read or written. This message pipe " | 490 << "the pipe can be sent after it's read or written. This message pipe " |
484 << "was previously bound at:\n" | 491 << "was previously bound at:\n" |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1082 // PostTask since the broker can call us back synchronously. | 1089 // PostTask since the broker can call us back synchronously. |
1083 internal::g_io_thread_task_runner->PostTask( | 1090 internal::g_io_thread_task_runner->PostTask( |
1084 FROM_HERE, | 1091 FROM_HERE, |
1085 base::Bind(&Broker::ConnectMessagePipe, | 1092 base::Bind(&Broker::ConnectMessagePipe, |
1086 base::Unretained(internal::g_broker), pipe_id_, | 1093 base::Unretained(internal::g_broker), pipe_id_, |
1087 base::Unretained(this))); | 1094 base::Unretained(this))); |
1088 } | 1095 } |
1089 | 1096 |
1090 } // namespace edk | 1097 } // namespace edk |
1091 } // namespace mojo | 1098 } // namespace mojo |
OLD | NEW |