Bug 993080 - 'MOZ_CRASH(nsStandardURL not thread-safe) in RemoteOpenFileChild::~RemoteOpenFileChild'. r=khuey.
authorBen Turner <bent.mozilla@gmail.com>
Mon, 07 Apr 2014 16:39:42 -0700
changeset 196970 30c9030026f188b47d47698080c8c364cf15c9af
parent 196916 488caa16c617edb0bef00719f426eb001247ee46
child 196971 04a44359d0242a6b4e7e3919b234c0d3b5b90282
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey
bugs993080
milestone31.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 993080 - 'MOZ_CRASH(nsStandardURL not thread-safe) in RemoteOpenFileChild::~RemoteOpenFileChild'. r=khuey.
netwerk/ipc/RemoteOpenFileChild.cpp
--- a/netwerk/ipc/RemoteOpenFileChild.cpp
+++ b/netwerk/ipc/RemoteOpenFileChild.cpp
@@ -1,23 +1,25 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et tw=80 : */
 /* 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/. */
 
-#include "mozilla/net/RemoteOpenFileChild.h"
+#include "RemoteOpenFileChild.h"
 
+#include "mozilla/unused.h"
 #include "mozilla/ipc/FileDescriptor.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/net/NeckoChild.h"
 #include "nsThreadUtils.h"
 #include "nsJARProtocolHandler.h"
 #include "nsIRemoteOpenFileListener.h"
+#include "nsProxyRelease.h"
 
 // needed to alloc/free NSPR file descriptors
 #include "private/pprio.h"
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
@@ -78,18 +80,50 @@ RemoteOpenFileChild::RemoteOpenFileChild
   if (other.mAppURI) {
     other.mAppURI->Clone(getter_AddRefs(mAppURI));
   }
   other.mFile->Clone(getter_AddRefs(mFile));
 }
 
 RemoteOpenFileChild::~RemoteOpenFileChild()
 {
-  if (mListener) {
-    NotifyListener(NS_ERROR_UNEXPECTED);
+  if (NS_IsMainThread()) {
+    if (mListener) {
+      NotifyListener(NS_ERROR_UNEXPECTED);
+    }
+  } else {
+    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+    if (mainThread) {
+      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mURI, true)));
+      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mAppURI, true)));
+      MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_ProxyRelease(mainThread, mListener,
+                                                   true)));
+
+      TabChild* tabChild;
+      mTabChild.forget(&tabChild);
+
+      if (tabChild) {
+        nsCOMPtr<nsIRunnable> runnable =
+          NS_NewNonOwningRunnableMethod(tabChild, &TabChild::Release);
+        MOZ_ASSERT(runnable);
+
+        MOZ_ALWAYS_TRUE(NS_SUCCEEDED(mainThread->Dispatch(runnable,
+                                                          NS_DISPATCH_NORMAL)));
+      }
+    } else {
+      using mozilla::unused;
+
+      NS_WARNING("RemoteOpenFileChild released after thread shutdown, leaking "
+                 "its members!");
+
+      unused << mURI.forget();
+      unused << mAppURI.forget();
+      unused << mListener.forget();
+      unused << mTabChild.forget();
+    }
   }
 
   if (mNSPRFileDesc) {
     // If we handed out fd we shouldn't have pointer to it any more.
     MOZ_ASSERT(!mNSPROpenCalled);
     // PR_Close both closes the file and deallocates the PRFileDesc
     PR_Close(mNSPRFileDesc);
   }