Bug 878366 - Don't send send out messages of PContendPermissionRequest if the managing TabParent is being destroyed. r=bent, a=koi+
authorCervantes Yu <cyu@mozilla.com>
Thu, 17 Oct 2013 06:25:50 +0800
changeset 160891 f9931a182295b5c934bb5cc9f3e0b69d57830ff4
parent 160890 c71d8cd3ddee0d468ab5e721dc951a75dfc1cfbc
child 160892 32bc5b2be9dd725b2fbda5615f286c0c83f5ed05
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, koi
bugs878366
milestone26.0a2
Bug 878366 - Don't send send out messages of PContendPermissionRequest if the managing TabParent is being destroyed. r=bent, a=koi+
dom/base/nsContentPermissionHelper.cpp
dom/base/nsContentPermissionHelper.h
dom/ipc/TabParent.h
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsContentPermissionHelper.h"
 #include "nsIContentPermissionPrompt.h"
 #include "nsCOMPtr.h"
 #include "nsIDOMElement.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/Element.h"
+#include "mozilla/dom/TabParent.h"
 #include "mozilla/unused.h"
 
 using mozilla::unused;          // <snicker>
 using namespace mozilla::dom;
 
 nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
 {
   MOZ_COUNT_CTOR(nsContentPermissionRequestProxy);
@@ -99,27 +100,40 @@ nsContentPermissionRequestProxy::GetElem
 
 NS_IMETHODIMP
 nsContentPermissionRequestProxy::Cancel()
 {
   if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
   }
 
+  // Don't send out the delete message when the managing protocol (PBrowser) is
+  // being destroyed and PContentPermissionRequest will soon be.
+  if (mParent->IsBeingDestroyed()) {
+    return NS_ERROR_FAILURE;
+  }
+
   unused << ContentPermissionRequestParent::Send__delete__(mParent, false);
   mParent = nullptr;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsContentPermissionRequestProxy::Allow()
 {
   if (mParent == nullptr) {
     return NS_ERROR_FAILURE;
   }
+
+  // Don't send out the delete message when the managing protocol (PBrowser) is
+  // being destroyed and PContentPermissionRequest will soon be.
+  if (mParent->IsBeingDestroyed()) {
+    return NS_ERROR_FAILURE;
+  }
+
   unused << ContentPermissionRequestParent::Send__delete__(mParent, true);
   mParent = nullptr;
   return NS_OK;
 }
 
 namespace mozilla {
 namespace dom {
 
@@ -155,10 +169,19 @@ ContentPermissionRequestParent::Recvprom
 void
 ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
 {
   if (mProxy) {
     mProxy->OnParentDestroyed();
   }
 }
 
+bool
+ContentPermissionRequestParent::IsBeingDestroyed()
+{
+  // When TabParent::Destroy() is called, we are being destroyed. It's unsafe
+  // to send out any message now.
+  TabParent* tabParent = static_cast<TabParent*>(Manager());
+  return tabParent->IsDestroyed();
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/nsContentPermissionHelper.h
+++ b/dom/base/nsContentPermissionHelper.h
@@ -22,16 +22,18 @@ class ContentPermissionRequestParent : p
 {
  public:
   ContentPermissionRequestParent(const nsACString& type,
                                  const nsACString& access,
                                  Element* element,
                                  const IPC::Principal& principal);
   virtual ~ContentPermissionRequestParent();
 
+  bool IsBeingDestroyed();
+
   nsCOMPtr<nsIPrincipal> mPrincipal;
   nsCOMPtr<Element> mElement;
   nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
   nsCString mType;
   nsCString mAccess;
 
  private:
   virtual bool Recvprompt();
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -232,16 +232,22 @@ public:
     bool SendTextEvent(nsTextEvent& event);
     bool SendSelectionEvent(nsSelectionEvent& event);
 
     static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
     static TabParent* GetFrom(nsIContent* aContent);
 
     ContentParent* Manager() { return mManager; }
 
+    /**
+     * Let managees query if Destroy() is already called so they don't send out
+     * messages when the PBrowser actor is being destroyed.
+     */
+    bool IsDestroyed() const { return mIsDestroyed; }
+
 protected:
     bool ReceiveMessage(const nsString& aMessage,
                         bool aSync,
                         const StructuredCloneData* aCloneData,
                         CpowHolder* aCpows,
                         InfallibleTArray<nsString>* aJSONRetVal = nullptr);
 
     virtual bool Recv__delete__() MOZ_OVERRIDE;