Bug 1006530 - Closing a audio RTSP streaming via tab page causes system crash. r=sworkman, a=bajaj
authorEthan Tseng <ettseng@mozilla.com>
Thu, 08 May 2014 16:16:11 +0800
changeset 192297 4f28715f9db6
parent 192296 51262a06149a
child 192298 c4006560b2cd
child 192300 859a8098cd8d
push id3561
push userryanvm@gmail.com
push date2014-05-15 17:43 +0000
treeherdermozilla-beta@4f28715f9db6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssworkman, bajaj
bugs1006530
milestone30.0
Bug 1006530 - Closing a audio RTSP streaming via tab page causes system crash. r=sworkman, a=bajaj
netwerk/protocol/rtsp/controller/RtspControllerParent.cpp
netwerk/protocol/rtsp/controller/RtspControllerParent.h
--- a/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp
+++ b/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp
@@ -2,16 +2,18 @@
 /* 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 "RtspControllerParent.h"
 #include "RtspController.h"
 #include "nsIAuthPromptProvider.h"
+#include "nsThreadUtils.h"
+#include "nsProxyRelease.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/unused.h"
 #include "nsNetUtil.h"
 #include "prlog.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -27,19 +29,41 @@ PRLogModuleInfo* gRtspLog;
     }                                                        \
   }
 
 using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
-NS_IMPL_ISUPPORTS2(RtspControllerParent,
-                   nsIInterfaceRequestor,
-                   nsIStreamingProtocolListener)
+void
+RtspControllerParent::Destroy()
+{
+  // If we're being destroyed on a non-main thread, we AddRef again and use a
+  // proxy to release the RtspControllerParent on the main thread, where the
+  // RtspControllerParent is deleted. This ensures we only delete the
+  // RtspControllerParent on the main thread.
+  if (!NS_IsMainThread()) {
+    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+    NS_ENSURE_TRUE_VOID(mainThread);
+    nsRefPtr<RtspControllerParent> doomed(this);
+    if (NS_FAILED(NS_ProxyRelease(mainThread,
+            static_cast<nsIStreamingProtocolListener*>(doomed), true))) {
+      NS_WARNING("Failed to proxy release to main thread!");
+    }
+  } else {
+    delete this;
+  }
+}
+
+NS_IMPL_ADDREF(RtspControllerParent)
+NS_IMPL_RELEASE_WITH_DESTROY(RtspControllerParent, Destroy())
+NS_IMPL_QUERY_INTERFACE2(RtspControllerParent,
+                         nsIInterfaceRequestor,
+                         nsIStreamingProtocolListener)
 
 RtspControllerParent::RtspControllerParent()
   : mIPCOpen(true)
   , mTotalTracks(0)
 {
 #if defined(PR_LOGGING)
   if (!gRtspLog)
     gRtspLog = PR_NewLogModule("nsRtsp");
--- a/netwerk/protocol/rtsp/controller/RtspControllerParent.h
+++ b/netwerk/protocol/rtsp/controller/RtspControllerParent.h
@@ -44,13 +44,15 @@ class RtspControllerParent : public PRts
  private:
   bool mIPCOpen;
   void ActorDestroy(ActorDestroyReason why);
   // RTSP URL refer to a stream or an aggregate of streams.
   nsCOMPtr<nsIURI> mURI;
   // The nsIStreamingProtocolController implementation.
   nsCOMPtr<nsIStreamingProtocolController> mController;
   uint32_t mTotalTracks;
+  // Ensure we are destroyed on the main thread.
+  void Destroy();
 };
 
 } // namespace net
 } // namespace mozilla
 #endif // RtspControllerParent_h