Bug 822158: Use async dispatch of Ice(Gathering)Completed to unwind stack r=jesup,ekr
authorJan-Ivar Bruaroey <jib@mozilla.com>
Fri, 21 Dec 2012 15:21:15 -0500
changeset 125975 46ab2a002a9bfd3d4617651065e51b96e014f35c
parent 125974 a1864cbae86c1ef0d1368dd1838d2e940f4b6420
child 125976 6546477eb93d19bf80f06afec712176512cabe80
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjesup, ekr
bugs822158
milestone20.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 822158: Use async dispatch of Ice(Gathering)Completed to unwind stack r=jesup,ekr
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -891,16 +891,18 @@ PeerConnectionImpl::GetIceState(uint32_t
 nsresult
 PeerConnectionImpl::CheckApiState(bool assert_ice_ready) const
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   PR_ASSERT(!assert_ice_ready || (mIceState != kIceGathering));
 
   if (mReadyState == kClosed)
     return NS_ERROR_FAILURE;
+  if (!mMedia)
+    return NS_ERROR_FAILURE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 PeerConnectionImpl::Close(bool aIsSynchronous)
 {
   CSFLogDebugS(logTag, __FUNCTION__);
   PC_AUTO_ENTER_API_CALL(false);
@@ -1040,75 +1042,81 @@ PeerConnectionImpl::GetHandle()
   return mHandle;
 }
 
 // This is called from the STS thread and so we need to thunk
 // to the main thread.
 void
 PeerConnectionImpl::IceGatheringCompleted(NrIceCtx *aCtx)
 {
+  // Do an async call here to unwind the stack. refptr keeps the PC alive.
+  nsRefPtr<PeerConnectionImpl> pc(this);
   RUN_ON_THREAD(mThread,
-                WrapRunnable(this,
+                WrapRunnable(pc,
                              &PeerConnectionImpl::IceGatheringCompleted_m,
                              aCtx),
-                NS_DISPATCH_SYNC);
+                NS_DISPATCH_NORMAL);
 }
 
-void
+nsresult
 PeerConnectionImpl::IceGatheringCompleted_m(NrIceCtx *aCtx)
 {
-  PC_AUTO_ENTER_API_CALL_NO_CHECK();
+  PC_AUTO_ENTER_API_CALL(false);
   MOZ_ASSERT(aCtx);
 
   CSFLogDebugS(logTag, __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx));
 
   mIceState = kIceWaiting;
 
 #ifdef MOZILLA_INTERNAL_API
   if (mPCObserver) {
     RUN_ON_THREAD(mThread,
                   WrapRunnable(mPCObserver,
                                &IPeerConnectionObserver::OnStateChange,
                                // static_cast required to work around old C++ compiler on Android NDK r5c
                                static_cast<int>(IPeerConnectionObserver::kIceState)),
                   NS_DISPATCH_NORMAL);
   }
 #endif
+  return NS_OK;
 }
 
 void
 PeerConnectionImpl::IceCompleted(NrIceCtx *aCtx)
 {
+  // Do an async call here to unwind the stack. refptr keeps the PC alive.
+  nsRefPtr<PeerConnectionImpl> pc(this);
   RUN_ON_THREAD(mThread,
-                WrapRunnable(this,
+                WrapRunnable(pc,
                              &PeerConnectionImpl::IceCompleted_m,
                              aCtx),
-                NS_DISPATCH_SYNC);
+                NS_DISPATCH_NORMAL);
 }
 
-void
+nsresult
 PeerConnectionImpl::IceCompleted_m(NrIceCtx *aCtx)
 {
-  PC_AUTO_ENTER_API_CALL_NO_CHECK();
+  PC_AUTO_ENTER_API_CALL(false);
   MOZ_ASSERT(aCtx);
 
   CSFLogDebugS(logTag, __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx));
 
   mIceState = kIceConnected;
 
 #ifdef MOZILLA_INTERNAL_API
   if (mPCObserver) {
     RUN_ON_THREAD(mThread,
                   WrapRunnable(mPCObserver,
                                &IPeerConnectionObserver::OnStateChange,
                                // static_cast required to work around old C++ compiler on Android NDK r5c
 			       static_cast<int>(IPeerConnectionObserver::kIceState)),
                   NS_DISPATCH_NORMAL);
   }
 #endif
+  return NS_OK;
 }
 
 void
 PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream)
 {
   PC_AUTO_ENTER_API_CALL_NO_CHECK();
   MOZ_ASSERT(aStream);
 
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.h
@@ -212,18 +212,18 @@ private:
 #endif
     return true;
   }
 
   // Shut down media. Called on any thread.
   void ShutdownMedia(bool isSynchronous);
 
   // ICE callbacks run on the right thread.
-  void IceGatheringCompleted_m(NrIceCtx *aCtx);
-  void IceCompleted_m(NrIceCtx *aCtx);
+  nsresult IceGatheringCompleted_m(NrIceCtx *aCtx);
+  nsresult IceCompleted_m(NrIceCtx *aCtx);
 
   // The role we are adopting
   Role mRole;
 
   // The call
   CSF::CC_CallPtr mCall;
   ReadyState mReadyState;
 
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -240,16 +240,18 @@ PeerConnectionMedia::DisconnectMediaStre
 
   mLocalSourceStreams.Clear();
   mRemoteSourceStreams.Clear();
 }
 
 void
 PeerConnectionMedia::ShutdownMediaTransport()
 {
+  mIceCtx->SignalCompleted.disconnect(this);
+  mIceCtx->SignalGatheringCompleted.disconnect(this);
   mTransportFlows.clear();
   mIceStreams.clear();
   mIceCtx = NULL;
 }
 
 LocalSourceStreamInfo*
 PeerConnectionMedia::GetLocalStream(int aIndex)
 {