Bug 1369571 - Break reference cycle between HttpChannelChild and HttpBackgroundChannelChild while PHttpChannel is destroyed. r=mayhemer, a=jcristau FIREFOX_RELEASE_55_BASE
authorShih-Chiang Chien <schien@mozilla.com>
Tue, 18 Jul 2017 19:03:14 +0800
changeset 412147 2cd8c7f13e6c5ace6955da85a4d95f6e65caad2e
parent 412146 c5cb6429eb36cf2c3110d464f95b8760ae1c524a
child 412148 255a5ed0ca253ccf92d088b9bc871df1f8735f1b
push id7562
push userryanvm@gmail.com
push dateMon, 31 Jul 2017 11:58:51 +0000
treeherdermozilla-beta@2cd8c7f13e6c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer, jcristau
bugs1369571
milestone55.0
Bug 1369571 - Break reference cycle between HttpChannelChild and HttpBackgroundChannelChild while PHttpChannel is destroyed. r=mayhemer, a=jcristau The reference cycle is supposed to be removed when HttpBackgroundChannelChild::ActorDestroyed, however this operation is pending due until HttpChannelChild receives OnStartRequest IPC message. Unfortunately the OnStartRequest IPC message is dropped because of PContent shutdown procedure. So, the reference removal is never executed, which leaks memory until content process is terminated. MozReview-Commit-ID: 7R6nt7W690o
netwerk/protocol/http/HttpBackgroundChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/HttpChannelChild.h
--- a/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
+++ b/netwerk/protocol/http/HttpBackgroundChannelChild.cpp
@@ -111,16 +111,19 @@ HttpBackgroundChannelChild::Init(HttpCha
 void
 HttpBackgroundChannelChild::OnChannelClosed()
 {
   LOG(("HttpBackgroundChannelChild::OnChannelClosed [this=%p]\n", this));
   MOZ_ASSERT(NS_IsMainThread());
 
   // HttpChannelChild is not going to handle any incoming message.
   mChannelChild = nullptr;
+
+  // Remove pending IPC messages as well.
+  mQueuedRunnables.Clear();
 }
 
 void
 HttpBackgroundChannelChild::OnStartRequestReceived()
 {
   LOG(("HttpBackgroundChannelChild::OnStartRequestReceived [this=%p]\n", this));
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(mChannelChild);
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -3505,10 +3505,23 @@ HttpChannelChild::ShouldInterceptURI(nsI
 
 mozilla::ipc::IPCResult
 HttpChannelChild::RecvSetPriority(const int16_t& aPriority)
 {
   mPriority = aPriority;
   return IPC_OK();
 }
 
+void
+HttpChannelChild::ActorDestroy(ActorDestroyReason aWhy)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+
+  // OnStartRequest might be dropped if IPDL is destroyed abnormally
+  // and BackgroundChild might have pending IPC messages.
+  // Clean up BackgroundChild at this time to prevent memleak.
+  if (aWhy != Deletion) {
+    CleanupBackgroundChannel();
+  }
+}
+
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/HttpChannelChild.h
+++ b/netwerk/protocol/http/HttpChannelChild.h
@@ -155,16 +155,18 @@ protected:
   mozilla::ipc::IPCResult RecvReportSecurityMessage(const nsString& messageTag,
                                                     const nsString& messageCategory) override;
 
   mozilla::ipc::IPCResult RecvIssueDeprecationWarning(const uint32_t& warning,
                                                       const bool& asError) override;
 
   mozilla::ipc::IPCResult RecvSetPriority(const int16_t& aPriority) override;
 
+  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
   MOZ_MUST_USE bool
   GetAssociatedContentSecurity(nsIAssociatedContentSecurity** res = nullptr);
   virtual void DoNotifyListenerCleanup() override;
 
   NS_IMETHOD GetResponseSynthesized(bool* aSynthesized) override;
 
   nsresult
   AsyncCall(void (HttpChannelChild::*funcPtr)(),