Bug 878366: don't send send out messages of PContendPermissionRequest if the managing TabParent is being destroyed. r=bent
authorCervantes Yu <cyu@mozilla.com>
Thu, 17 Oct 2013 06:25:50 +0800
changeset 152205 810cb9568dbfe6c8bbe7b291723d5b77cec4660f
parent 152204 d83ee71140920dcca697ed3fc6ebf45fad4ea9f0
child 152206 c5a70830dc9a4643430c89274fb33d26ba235176
push idunknown
push userunknown
push dateunknown
reviewersbent
bugs878366
milestone27.0a1
Bug 878366: don't send send out messages of PContendPermissionRequest if the managing TabParent is being destroyed. r=bent
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"
 #include "nsComponentManagerUtils.h"
 
 using mozilla::unused;          // <snicker>
 using namespace mozilla::dom;
 
 nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
 {
@@ -100,27 +101,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 {
 
@@ -156,10 +170,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
@@ -233,16 +233,22 @@ public:
     bool SendTextEvent(mozilla::WidgetTextEvent& event);
     bool SendSelectionEvent(mozilla::WidgetSelectionEvent& 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;