Index: mojo/edk/system/message_pipe_dispatcher.cc |
diff --git a/mojo/edk/system/message_pipe_dispatcher.cc b/mojo/edk/system/message_pipe_dispatcher.cc |
index 63b87813a714152f179d8b2e09f48a9cc85cf10c..75f7227c9296e86531653c48bda07fc8ffd15453 100644 |
--- a/mojo/edk/system/message_pipe_dispatcher.cc |
+++ b/mojo/edk/system/message_pipe_dispatcher.cc |
@@ -154,6 +154,7 @@ void MessagePipeDispatcher::InitOnIO() { |
void MessagePipeDispatcher::CloseOnIO() { |
base::AutoLock locker(lock()); |
+ Release(); // To match CloseImplNoLock. |
if (transferable_) { |
if (channel_) { |
channel_->Shutdown(); |
@@ -435,6 +436,12 @@ void MessagePipeDispatcher::CancelAllAwakablesNoLock() { |
void MessagePipeDispatcher::CloseImplNoLock() { |
lock().AssertAcquired(); |
+ // We take a manual refcount because at shutdown, the task below might not get |
+ // 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
|
+ // 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
|
+ // destruction). So to avoid UAF, manually add a reference and only release it |
+ // if the task runs. |
+ AddRef(); |
internal::g_io_thread_task_runner->PostTask( |
FROM_HERE, base::Bind(&MessagePipeDispatcher::CloseOnIO, this)); |
} |