From 05b9752a11d98fc04d9f46089ce29d4b9ae77adc Mon Sep 17 00:00:00 2001 From: Benjamin Smedberg Date: Thu, 5 Jul 2012 14:48:40 -0400 Subject: [PATCH] Bug 770805 - Close the IPC channel safely when we discover that a Flash process has crashed; don't call Close() directly, because PluginModuleParent assumes that a normal shutdown only occurs from PluginModuleParent::NP_Shutdown. Instead, follow a similar codepath to the hang timeout which calls AsyncChannel::SynchronouslyClose and then sets a specific error code, r=cjones --- dom/plugins/ipc/PluginModuleParent.cpp | 7 +------ ipc/glue/AsyncChannel.cpp | 20 ++++++++++++++++++-- ipc/glue/AsyncChannel.h | 4 ++++ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index a606f6398179..b81801dff41c 100644 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -1274,12 +1274,7 @@ PluginModuleParent::OnCrash(DWORD processID, const nsAString& aDumpID) NS_ERROR("Got minidump for Flash process neither broker nor sandbox."); } - CrashReporter::AppendExtraData(aDumpID, notes); - MessageLoop::current()->PostTask( - FROM_HERE, - mTaskFactory.NewRunnableMethod( - &PluginModuleParent::CleanupFromTimeout)); - + GetIPCChannel()->CloseWithError(); KillProcess(OtherProcess(), 1, false); } diff --git a/ipc/glue/AsyncChannel.cpp b/ipc/glue/AsyncChannel.cpp index 8ed07d0a6d97..af1b5b278a86 100644 --- a/ipc/glue/AsyncChannel.cpp +++ b/ipc/glue/AsyncChannel.cpp @@ -482,6 +482,8 @@ AsyncChannel::OnNotifyMaybeChannelError() AssertWorkerThread(); mMonitor->AssertNotCurrentThreadOwns(); + mChannelErrorTask = NULL; + // OnChannelError holds mMonitor when it posts this task and this // task cannot be allowed to run until OnChannelError has // exited. We enforce that order by grabbing the mutex here which @@ -744,12 +746,26 @@ AsyncChannel::OnChannelErrorFromLink() } void +AsyncChannel::CloseWithError() +{ + AssertWorkerThread(); + + MonitorAutoLock lock(*mMonitor); + if (ChannelConnected != mChannelState) { + return; + } + SynchronouslyClose(); + mChannelState = ChannelError; + PostErrorNotifyTask(); +} + +void AsyncChannel::PostErrorNotifyTask() { - AssertLinkThread(); mMonitor->AssertCurrentThreadOwns(); - NS_ASSERTION(!mChannelErrorTask, "OnChannelError called twice?"); + if (mChannelErrorTask) + return; // This must be the last code that runs on this thread! mChannelErrorTask = diff --git a/ipc/glue/AsyncChannel.h b/ipc/glue/AsyncChannel.h index 637f79db422d..60df7ed56669 100644 --- a/ipc/glue/AsyncChannel.h +++ b/ipc/glue/AsyncChannel.h @@ -103,6 +103,10 @@ public: // Close the underlying transport channel. void Close(); + // Force the channel to behave as if a channel error occurred. Valid + // for process links only, not thread links. + void CloseWithError(); + // Asynchronously send a message to the other side of the channel virtual bool Send(Message* msg); -- 2.11.4.GIT