Bug 1540731 - Part 3: Stop releasing actors within ActorDestroy, r=mayhemer
authorNika Layzell <nika@thelayzells.com>
Tue, 21 May 2019 17:04:23 +0000
changeset 474783 11450b71e95eaf5fdb8bbc5e424dc9cc2aafcd61
parent 474782 89b214d41e5050aa849bfa6b540b83b4693ffd1d
child 474784 969f29e56fa1b018fe790d888e05df6f1ddbdbb1
push id36046
push useraiakab@mozilla.com
push dateTue, 21 May 2019 21:45:52 +0000
treeherdermozilla-central@257f2c96cef5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1540731
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1540731 - Part 3: Stop releasing actors within ActorDestroy, r=mayhemer Differential Revision: https://phabricator.services.mozilla.com/D29606
netwerk/base/SimpleChannel.cpp
netwerk/base/SimpleChannel.h
netwerk/base/moz.build
netwerk/base/nsBaseChannel.h
netwerk/ipc/NeckoChild.cpp
netwerk/protocol/data/DataChannelChild.cpp
netwerk/protocol/data/moz.build
netwerk/protocol/file/FileChannelChild.cpp
netwerk/protocol/file/moz.build
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/http/HttpBaseChannel.h
uriloader/exthandler/ExternalHelperAppParent.h
--- a/netwerk/base/SimpleChannel.cpp
+++ b/netwerk/base/SimpleChannel.cpp
@@ -16,33 +16,16 @@
 #include "mozilla/Unused.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/net/PSimpleChannelChild.h"
 
 namespace mozilla {
 namespace net {
 
-class SimpleChannel : public nsBaseChannel {
- public:
-  explicit SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
-
- protected:
-  virtual ~SimpleChannel() = default;
-
-  virtual nsresult OpenContentStream(bool async, nsIInputStream** streamOut,
-                                     nsIChannel** channel) override;
-
-  virtual nsresult BeginAsyncRead(nsIStreamListener* listener,
-                                  nsIRequest** request) override;
-
- private:
-  UniquePtr<SimpleChannelCallbacks> mCallbacks;
-};
-
 SimpleChannel::SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
     : mCallbacks(std::move(aCallbacks)) {
   EnableSynthesizedProgressEvents(true);
 }
 
 nsresult SimpleChannel::OpenContentStream(bool async,
                                           nsIInputStream** streamOut,
                                           nsIChannel** channel) {
@@ -67,85 +50,60 @@ nsresult SimpleChannel::BeginAsyncRead(n
   MOZ_TRY_VAR(req, mCallbacks->StartAsyncRead(listener, this));
 
   mCallbacks = nullptr;
 
   req.forget(request);
   return NS_OK;
 }
 
-class SimpleChannelChild final : public SimpleChannel,
-                                 public nsIChildChannel,
-                                 public PSimpleChannelChild {
- public:
-  explicit SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSICHILDCHANNEL
-
- protected:
-  virtual void ActorDestroy(ActorDestroyReason why) override;
-
- private:
-  virtual ~SimpleChannelChild() = default;
-
-  void AddIPDLReference();
-
-  RefPtr<SimpleChannelChild> mIPDLRef;
-};
-
 NS_IMPL_ISUPPORTS_INHERITED(SimpleChannelChild, SimpleChannel, nsIChildChannel)
 
 SimpleChannelChild::SimpleChannelChild(
     UniquePtr<SimpleChannelCallbacks>&& aCallbacks)
-    : SimpleChannel(std::move(aCallbacks)), mIPDLRef(nullptr) {}
+    : SimpleChannel(std::move(aCallbacks)) {}
 
 NS_IMETHODIMP
 SimpleChannelChild::ConnectParent(uint32_t aId) {
   MOZ_ASSERT(NS_IsMainThread());
   mozilla::dom::ContentChild* cc =
       static_cast<mozilla::dom::ContentChild*>(gNeckoChild->Manager());
   if (cc->IsShuttingDown()) {
     return NS_ERROR_FAILURE;
   }
 
-  if (!gNeckoChild->SendPSimpleChannelConstructor(this, aId)) {
+  // Reference freed in DeallocPSimpleChannelChild.
+  if (!gNeckoChild->SendPSimpleChannelConstructor(do_AddRef(this).take(),
+                                                  aId)) {
     return NS_ERROR_FAILURE;
   }
 
-  // IPC now has a ref to us.
-  mIPDLRef = this;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 SimpleChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener,
                                           nsISupports* aContext) {
-  if (mIPDLRef) {
+  if (CanSend()) {
     MOZ_ASSERT(NS_IsMainThread());
   }
 
   nsresult rv;
   MOZ_ASSERT(!aContext, "aContext should be null!");
   rv = AsyncOpen(aListener);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
-  if (mIPDLRef) {
+  if (CanSend()) {
     Unused << Send__delete__(this);
   }
   return NS_OK;
 }
 
-void SimpleChannelChild::ActorDestroy(ActorDestroyReason why) {
-  MOZ_ASSERT(mIPDLRef);
-  mIPDLRef = nullptr;
-}
-
 already_AddRefed<nsIChannel> NS_NewSimpleChannelInternal(
     nsIURI* aURI, nsILoadInfo* aLoadInfo,
     UniquePtr<SimpleChannelCallbacks>&& aCallbacks) {
   RefPtr<SimpleChannel> chan;
   if (IsNeckoChild()) {
     chan = new SimpleChannelChild(std::move(aCallbacks));
   } else {
     chan = new SimpleChannel(std::move(aCallbacks));
--- a/netwerk/base/SimpleChannel.h
+++ b/netwerk/base/SimpleChannel.h
@@ -3,16 +3,19 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef SimpleChannel_h
 #define SimpleChannel_h
 
 #include "mozilla/ResultExtensions.h"
 #include "mozilla/UniquePtr.h"
+#include "nsBaseChannel.h"
+#include "nsIChildChannel.h"
+#include "mozilla/net/PSimpleChannelChild.h"
 #include "nsCOMPtr.h"
 
 class nsIChannel;
 class nsIInputStream;
 class nsILoadInfo;
 class nsIRequest;
 class nsIStreamListener;
 class nsIURI;
@@ -59,16 +62,46 @@ class SimpleChannelCallbacksImpl final :
   }
 
  private:
   F1 mStartAsyncRead;
   F2 mOpenContentStream;
   RefPtr<T> mContext;
 };
 
+class SimpleChannel : public nsBaseChannel {
+ public:
+  explicit SimpleChannel(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
+
+ protected:
+  virtual ~SimpleChannel() = default;
+
+  virtual nsresult OpenContentStream(bool async, nsIInputStream** streamOut,
+                                     nsIChannel** channel) override;
+
+  virtual nsresult BeginAsyncRead(nsIStreamListener* listener,
+                                  nsIRequest** request) override;
+
+ private:
+  UniquePtr<SimpleChannelCallbacks> mCallbacks;
+};
+
+class SimpleChannelChild final : public SimpleChannel,
+                                 public nsIChildChannel,
+                                 public PSimpleChannelChild {
+ public:
+  explicit SimpleChannelChild(UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
+
+  NS_DECL_ISUPPORTS_INHERITED
+  NS_DECL_NSICHILDCHANNEL
+
+ private:
+  virtual ~SimpleChannelChild() = default;
+};
+
 already_AddRefed<nsIChannel> NS_NewSimpleChannelInternal(
     nsIURI* aURI, nsILoadInfo* aLoadInfo,
     UniquePtr<SimpleChannelCallbacks>&& aCallbacks);
 
 }  // namespace net
 }  // namespace mozilla
 
 /**
--- a/netwerk/base/moz.build
+++ b/netwerk/base/moz.build
@@ -130,16 +130,17 @@ XPIDL_SOURCES += [
 ]
 
 XPIDL_MODULE = 'necko'
 
 EXPORTS += [
     'netCore.h',
     'nsASocketHandler.h',
     'nsAsyncRedirectVerifyHelper.h',
+    'nsBaseChannel.h',
     'nsFileStreams.h',
     'nsInputStreamPump.h',
     'nsMIMEInputStream.h',
     'nsNetUtil.h',
     'nsReadLine.h',
     'nsSerializationHelper.h',
     'nsSimpleNestedURI.h',
     'nsSimpleURI.h',
@@ -164,16 +165,17 @@ EXPORTS.mozilla.net += [
     'ChannelDiverterParent.h',
     'Dashboard.h',
     'DashboardTypes.h',
     'IOActivityMonitor.h',
     'MemoryDownloader.h',
     'NetworkConnectivityService.h',
     'PartiallySeekableInputStream.h',
     'Predictor.h',
+    'PrivateBrowsingChannel.h',
     'RedirectChannelRegistrar.h',
     'ReferrerPolicy.h',
     'RequestContextService.h',
     'SimpleChannelParent.h',
     'SSLTokensCache.h',
     'TCPFastOpen.h',
 ]
 
--- a/netwerk/base/nsBaseChannel.h
+++ b/netwerk/base/nsBaseChannel.h
@@ -20,17 +20,17 @@
 #include "nsILoadInfo.h"
 #include "nsIStreamListener.h"
 #include "nsIInterfaceRequestor.h"
 #include "nsIProgressEventSink.h"
 #include "nsITransport.h"
 #include "nsIAsyncVerifyRedirectCallback.h"
 #include "nsIThreadRetargetableRequest.h"
 #include "nsIThreadRetargetableStreamListener.h"
-#include "PrivateBrowsingChannel.h"
+#include "mozilla/net/PrivateBrowsingChannel.h"
 #include "nsThreadUtils.h"
 
 class nsIInputStream;
 
 //-----------------------------------------------------------------------------
 // nsBaseChannel is designed to be subclassed.  The subclass is responsible for
 // implementing the OpenContentStream method, which will be called by the
 // nsIChannel::AsyncOpen and nsIChannel::Open implementations.
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -8,16 +8,18 @@
 #include "necko-config.h"
 #include "nsHttp.h"
 #include "mozilla/net/NeckoChild.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/BrowserChild.h"
 #include "mozilla/net/HttpChannelChild.h"
 #include "mozilla/net/CookieServiceChild.h"
 #include "mozilla/net/FTPChannelChild.h"
+#include "mozilla/net/DataChannelChild.h"
+#include "mozilla/net/FileChannelChild.h"
 #include "mozilla/net/WebSocketChannelChild.h"
 #include "mozilla/net/WebSocketEventListenerChild.h"
 #include "mozilla/net/DNSRequestChild.h"
 #include "mozilla/net/ChannelDiverterChild.h"
 #include "mozilla/net/IPCTransportProvider.h"
 #include "mozilla/dom/network/TCPSocketChild.h"
 #include "mozilla/dom/network/TCPServerSocketChild.h"
 #include "mozilla/dom/network/UDPSocketChild.h"
@@ -33,16 +35,17 @@
 #include "nsGlobalWindow.h"
 #include "nsIOService.h"
 #include "nsINetworkPredictor.h"
 #include "nsINetworkPredictorVerifier.h"
 #include "nsINetworkLinkService.h"
 #include "nsQueryObject.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "nsNetUtil.h"
+#include "SimpleChannel.h"
 
 using mozilla::dom::TCPServerSocketChild;
 using mozilla::dom::TCPSocketChild;
 using mozilla::dom::UDPSocketChild;
 
 namespace mozilla {
 namespace net {
 
@@ -215,39 +218,39 @@ bool NeckoChild::DeallocPWebSocketEventL
 
 PDataChannelChild* NeckoChild::AllocPDataChannelChild(
     const uint32_t& channelId) {
   MOZ_ASSERT_UNREACHABLE("Should never get here");
   return nullptr;
 }
 
 bool NeckoChild::DeallocPDataChannelChild(PDataChannelChild* child) {
-  // NB: See DataChannelChild::ActorDestroy.
+  static_cast<DataChannelChild*>(child)->Release();
   return true;
 }
 
 PFileChannelChild* NeckoChild::AllocPFileChannelChild(
     const uint32_t& channelId) {
   MOZ_ASSERT_UNREACHABLE("Should never get here");
   return nullptr;
 }
 
 bool NeckoChild::DeallocPFileChannelChild(PFileChannelChild* child) {
-  // NB: See FileChannelChild::ActorDestroy.
+  static_cast<FileChannelChild*>(child)->Release();
   return true;
 }
 
 PSimpleChannelChild* NeckoChild::AllocPSimpleChannelChild(
     const uint32_t& channelId) {
   MOZ_ASSERT_UNREACHABLE("Should never get here");
   return nullptr;
 }
 
 bool NeckoChild::DeallocPSimpleChannelChild(PSimpleChannelChild* child) {
-  // NB: See SimpleChannelChild::ActorDestroy.
+  static_cast<SimpleChannelChild*>(child)->Release();
   return true;
 }
 
 PTCPSocketChild* NeckoChild::AllocPTCPSocketChild(const nsString& host,
                                                   const uint16_t& port) {
   TCPSocketChild* p = new TCPSocketChild(host, port, nullptr);
   p->AddIPDLReference();
   return p;
--- a/netwerk/protocol/data/DataChannelChild.cpp
+++ b/netwerk/protocol/data/DataChannelChild.cpp
@@ -47,20 +47,19 @@ DataChannelChild::CompleteRedirectSetup(
 
   if (mIPCOpen) {
     Unused << Send__delete__(this);
   }
   return NS_OK;
 }
 
 void DataChannelChild::AddIPDLReference() {
-  AddRef();
+  AddRef();  // Released in NeckoChild::DeallocPDataChannelChild.
   mIPCOpen = true;
 }
 
 void DataChannelChild::ActorDestroy(ActorDestroyReason why) {
   MOZ_ASSERT(mIPCOpen);
   mIPCOpen = false;
-  Release();
 }
 
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/data/moz.build
+++ b/netwerk/protocol/data/moz.build
@@ -1,20 +1,22 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.net += [
+    'DataChannelChild.h',
     'DataChannelParent.h',
 ]
 
 EXPORTS += [
-  'nsDataHandler.h',
+    'nsDataChannel.h',
+    'nsDataHandler.h',
 ]
 
 UNIFIED_SOURCES += [
     'DataChannelChild.cpp',
     'DataChannelParent.cpp',
     'nsDataChannel.cpp',
     'nsDataHandler.cpp',
 ]
--- a/netwerk/protocol/file/FileChannelChild.cpp
+++ b/netwerk/protocol/file/FileChannelChild.cpp
@@ -48,20 +48,19 @@ FileChannelChild::CompleteRedirectSetup(
   if (mIPCOpen) {
     Unused << Send__delete__(this);
   }
 
   return NS_OK;
 }
 
 void FileChannelChild::AddIPDLReference() {
-  AddRef();
+  AddRef();  // Released in NeckoChild::DeallocPFileChannelChild.
   mIPCOpen = true;
 }
 
 void FileChannelChild::ActorDestroy(ActorDestroyReason why) {
   MOZ_ASSERT(mIPCOpen);
   mIPCOpen = false;
-  Release();
 }
 
 }  // namespace net
 }  // namespace mozilla
--- a/netwerk/protocol/file/moz.build
+++ b/netwerk/protocol/file/moz.build
@@ -3,20 +3,25 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'Networking: File')
 
 EXPORTS.mozilla.net += [
+    'FileChannelChild.h',
     'FileChannelParent.h',
     'nsFileProtocolHandler.h',
 ]
 
+EXPORTS += [
+    'nsFileChannel.h',
+]
+
 XPIDL_SOURCES += [
     'nsIFileChannel.idl',
     'nsIFileProtocolHandler.idl',
 ]
 
 XPIDL_MODULE = 'necko_file'
 
 UNIFIED_SOURCES += [
--- a/netwerk/protocol/ftp/FTPChannelChild.h
+++ b/netwerk/protocol/ftp/FTPChannelChild.h
@@ -16,17 +16,17 @@
 #include "nsIUploadChannel.h"
 #include "nsIProxiedChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsIChildChannel.h"
 #include "nsIDivertableChannel.h"
 #include "nsIEventTarget.h"
 
 #include "nsIStreamListener.h"
-#include "PrivateBrowsingChannel.h"
+#include "mozilla/net/PrivateBrowsingChannel.h"
 
 class nsIEventTarget;
 
 namespace mozilla {
 
 namespace net {
 
 // This class inherits logic from nsBaseChannel that is not needed for an
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -33,17 +33,17 @@
 #include "nsIClassifiedChannel.h"
 #include "nsIApplicationCache.h"
 #include "nsIResumableChannel.h"
 #include "nsITraceableChannel.h"
 #include "nsILoadContext.h"
 #include "nsILoadInfo.h"
 #include "mozilla/net/NeckoCommon.h"
 #include "nsThreadUtils.h"
-#include "PrivateBrowsingChannel.h"
+#include "mozilla/net/PrivateBrowsingChannel.h"
 #include "mozilla/net/DNS.h"
 #include "nsITimedChannel.h"
 #include "nsIHttpChannel.h"
 #include "nsISecurityConsoleMessage.h"
 #include "nsCOMArray.h"
 #include "mozilla/net/ChannelEventQueue.h"
 #include "mozilla/Move.h"
 #include "mozilla/Tuple.h"
--- a/uriloader/exthandler/ExternalHelperAppParent.h
+++ b/uriloader/exthandler/ExternalHelperAppParent.h
@@ -6,17 +6,17 @@
 
 #include "mozilla/dom/PExternalHelperAppParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "nsIChannel.h"
 #include "nsIMultiPartChannel.h"
 #include "nsIResumableChannel.h"
 #include "nsIStreamListener.h"
 #include "nsHashPropertyBag.h"
-#include "PrivateBrowsingChannel.h"
+#include "mozilla/net/PrivateBrowsingChannel.h"
 
 namespace IPC {
 class URI;
 }  // namespace IPC
 
 namespace mozilla {
 
 namespace ipc {