mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 824919: Weaken key references to PeerConnection and friends r=jesup,smaug,ekr
This commit is contained in:
parent
e514da1eed
commit
9c2697eb77
@ -56,13 +56,23 @@ GlobalPCList.prototype = {
|
||||
addPC: function(pc) {
|
||||
let winID = pc._winID;
|
||||
if (this._list[winID]) {
|
||||
this._list[winID].push(pc);
|
||||
this._list[winID].push(Components.utils.getWeakReference(pc));
|
||||
} else {
|
||||
this._list[winID] = [pc];
|
||||
this._list[winID] = [Components.utils.getWeakReference(pc)];
|
||||
}
|
||||
this.removeNullRefs(winID);
|
||||
},
|
||||
|
||||
removeNullRefs: function(winID) {
|
||||
if (this._list === undefined || this._list[winID] === undefined) {
|
||||
return;
|
||||
}
|
||||
this._list[winID] = this._list[winID].filter(
|
||||
function (e,i,a) { return e.get() !== null; });
|
||||
},
|
||||
|
||||
hasActivePeerConnection: function(winID) {
|
||||
this.removeNullRefs(winID);
|
||||
return this._list[winID] ? true : false;
|
||||
},
|
||||
|
||||
@ -70,10 +80,13 @@ GlobalPCList.prototype = {
|
||||
if (topic == "inner-window-destroyed") {
|
||||
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (this._list[winID]) {
|
||||
this._list[winID].forEach(function(pc) {
|
||||
pc._pc.close(false);
|
||||
delete pc._observer;
|
||||
pc._pc = null;
|
||||
this._list[winID].forEach(function(pcref) {
|
||||
let pc = pcref.get();
|
||||
if (pc !== null) {
|
||||
pc._pc.close(false);
|
||||
delete pc._observer;
|
||||
pc._pc = null;
|
||||
}
|
||||
});
|
||||
delete this._list[winID];
|
||||
}
|
||||
@ -85,10 +98,13 @@ GlobalPCList.prototype = {
|
||||
// while offline, but attempts to connect them should fail.
|
||||
let array;
|
||||
while ((array = this._list.pop()) != undefined) {
|
||||
array.forEach(function(pc) {
|
||||
pc._pc.close(true);
|
||||
delete pc._observer;
|
||||
pc._pc = null;
|
||||
array.forEach(function(pcref) {
|
||||
let pc = pcref.get();
|
||||
if (pc !== null) {
|
||||
pc._pc.close(true);
|
||||
delete pc._observer;
|
||||
pc._pc = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
this._networkdown = true;
|
||||
@ -230,7 +246,9 @@ PeerConnection.prototype = {
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIDOMRTCPeerConnection, Ci.nsIDOMGlobalObjectConstructor
|
||||
Ci.nsIDOMRTCPeerConnection,
|
||||
Ci.nsIDOMGlobalObjectConstructor,
|
||||
Ci.nsISupportsWeakReference
|
||||
]),
|
||||
|
||||
// Constructor is an explicit function, because of nsIDOMGlobalObjectConstructor.
|
||||
@ -538,7 +556,8 @@ function PeerConnectionObserver(dompc) {
|
||||
this._dompc = dompc;
|
||||
}
|
||||
PeerConnectionObserver.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.IPeerConnectionObserver]),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.IPeerConnectionObserver,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
onCreateOfferSuccess: function(offer) {
|
||||
if (this._dompc._onCreateOfferSuccess) {
|
||||
|
@ -41,10 +41,14 @@ public:
|
||||
if (!observerService)
|
||||
return;
|
||||
|
||||
nsresult rv = observerService->AddObserver(this,
|
||||
NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
false);
|
||||
MOZ_ASSERT(rv == NS_OK);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
rv = observerService->AddObserver(this,
|
||||
NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
false);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(rv));
|
||||
#endif
|
||||
(void) rv;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,9 @@ PeerConnectionImpl::PeerConnectionImpl()
|
||||
, mIdentity(NULL)
|
||||
, mSTSThread(NULL)
|
||||
, mMedia(new PeerConnectionMedia(this)) {
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
#endif
|
||||
}
|
||||
|
||||
PeerConnectionImpl::~PeerConnectionImpl()
|
||||
@ -293,10 +295,13 @@ NS_IMETHODIMP
|
||||
PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver,
|
||||
nsIDOMWindow* aWindow,
|
||||
nsIThread* aThread) {
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
#endif
|
||||
MOZ_ASSERT(aObserver);
|
||||
MOZ_ASSERT(aThread);
|
||||
mPCObserver = aObserver;
|
||||
|
||||
mPCObserver = do_GetWeakReference(aObserver);
|
||||
|
||||
nsresult res;
|
||||
|
||||
@ -526,8 +531,12 @@ PeerConnectionImpl::NotifyConnection()
|
||||
CSFLogDebugS(logTag, __FUNCTION__);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return;
|
||||
}
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnable(mPCObserver,
|
||||
WrapRunnable(pco,
|
||||
&IPeerConnectionObserver::NotifyConnection),
|
||||
NS_DISPATCH_NORMAL);
|
||||
#endif
|
||||
@ -541,10 +550,13 @@ PeerConnectionImpl::NotifyClosedConnection()
|
||||
CSFLogDebugS(logTag, __FUNCTION__);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return;
|
||||
}
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnable(mPCObserver,
|
||||
&IPeerConnectionObserver::NotifyClosedConnection),
|
||||
NS_DISPATCH_NORMAL);
|
||||
WrapRunnable(pco, &IPeerConnectionObserver::NotifyClosedConnection),
|
||||
NS_DISPATCH_NORMAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -570,15 +582,20 @@ PeerConnectionImpl::NotifyDataChannel(already_AddRefed<mozilla::DataChannel> aCh
|
||||
CSFLogDebugS(logTag, __FUNCTION__ << ": channel: " << static_cast<void*>(aChannel.get()));
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsCOMPtr<nsIDOMDataChannel> domchannel;
|
||||
nsresult rv = NS_NewDOMDataChannel(aChannel, mWindow,
|
||||
getter_AddRefs(domchannel));
|
||||
nsCOMPtr<nsIDOMDataChannel> domchannel;
|
||||
nsresult rv = NS_NewDOMDataChannel(aChannel, mWindow,
|
||||
getter_AddRefs(domchannel));
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return;
|
||||
}
|
||||
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnableNM(NotifyDataChannel_m,
|
||||
domchannel.get(),
|
||||
mPCObserver),
|
||||
pco),
|
||||
NS_DISPATCH_NORMAL);
|
||||
#endif
|
||||
}
|
||||
@ -1012,16 +1029,20 @@ PeerConnectionImpl::onCallEvent(ccapi_call_event_e aCallEvent,
|
||||
break;
|
||||
}
|
||||
|
||||
if (mPCObserver) {
|
||||
PeerConnectionObserverDispatch* runnable =
|
||||
new PeerConnectionObserverDispatch(aInfo, this, mPCObserver);
|
||||
|
||||
if (mThread) {
|
||||
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
runnable->Run();
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return;
|
||||
}
|
||||
|
||||
PeerConnectionObserverDispatch* runnable =
|
||||
new PeerConnectionObserverDispatch(aInfo, this, pco);
|
||||
|
||||
if (mThread) {
|
||||
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
runnable->Run();
|
||||
delete runnable;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1032,7 +1053,11 @@ PeerConnectionImpl::ChangeReadyState(PeerConnectionImpl::ReadyState aReadyState)
|
||||
|
||||
// Note that we are passing an nsRefPtr<IPeerConnectionObserver> which
|
||||
// keeps the observer live.
|
||||
RUN_ON_THREAD(mThread, WrapRunnable(mPCObserver,
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return;
|
||||
}
|
||||
RUN_ON_THREAD(mThread, WrapRunnable(pco,
|
||||
&IPeerConnectionObserver::OnStateChange,
|
||||
// static_cast needed to work around old Android NDK r5c compiler
|
||||
static_cast<int>(IPeerConnectionObserver::kReadyState)),
|
||||
@ -1086,14 +1111,16 @@ PeerConnectionImpl::IceGatheringCompleted_m(NrIceCtx *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);
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return NS_OK;
|
||||
}
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnable(pco,
|
||||
&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;
|
||||
}
|
||||
@ -1121,14 +1148,16 @@ PeerConnectionImpl::IceCompleted_m(NrIceCtx *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);
|
||||
nsCOMPtr<IPeerConnectionObserver> pco = do_QueryReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return NS_OK;
|
||||
}
|
||||
RUN_ON_THREAD(mThread,
|
||||
WrapRunnable(pco,
|
||||
&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;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include "prlock.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIWeakReferenceUtils.h" // for the definition of nsWeakPtr
|
||||
#include "IPeerConnection.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
@ -230,7 +232,9 @@ private:
|
||||
IceState mIceState;
|
||||
|
||||
nsCOMPtr<nsIThread> mThread;
|
||||
nsCOMPtr<IPeerConnectionObserver> mPCObserver;
|
||||
// Weak pointer to IPeerConnectionObserver
|
||||
// This is only safe to use on the main thread
|
||||
nsWeakPtr mPCObserver;
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
|
||||
// The SDP sent in from JS - here for debugging.
|
||||
|
@ -133,6 +133,7 @@ LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/src/peerconnection \
|
||||
-I$(topsrcdir)/media/webrtc/signaling/media-conduit\
|
||||
-I$(topsrcdir)/media/webrtc/trunk/third_party/libjingle/source/ \
|
||||
-I$(topsrcdir)/xpcom/base/ \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_TARGET),WINNT)
|
||||
|
@ -23,9 +23,11 @@ using namespace std;
|
||||
#include "FakeMediaStreams.h"
|
||||
#include "FakeMediaStreamsImpl.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionCtx.h"
|
||||
#include "runnable_utils.h"
|
||||
#include "nsStaticComponents.h"
|
||||
#include "nsIDOMRTCPeerConnection.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "mtransport_test_utils.h"
|
||||
MtransportTestUtils *test_utils;
|
||||
@ -118,7 +120,8 @@ enum offerAnswerFlags
|
||||
};
|
||||
|
||||
|
||||
class TestObserver : public IPeerConnectionObserver
|
||||
class TestObserver : public IPeerConnectionObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
enum Action {
|
||||
@ -163,7 +166,9 @@ private:
|
||||
std::vector<nsDOMMediaStream *> streams;
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(TestObserver, IPeerConnectionObserver)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(TestObserver,
|
||||
IPeerConnectionObserver,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
TestObserver::OnCreateOfferSuccess(const char* offer)
|
||||
@ -489,7 +494,7 @@ class SignalingAgent {
|
||||
NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
void Init(nsCOMPtr<nsIThread> thread)
|
||||
void Init_m(nsCOMPtr<nsIThread> thread)
|
||||
{
|
||||
size_t found = 2;
|
||||
ASSERT_TRUE(found > 0);
|
||||
@ -502,6 +507,14 @@ class SignalingAgent {
|
||||
|
||||
ASSERT_EQ(pc->Initialize(pObserver, nullptr, thread), NS_OK);
|
||||
|
||||
}
|
||||
|
||||
void Init(nsCOMPtr<nsIThread> thread)
|
||||
{
|
||||
thread->Dispatch(
|
||||
WrapRunnable(this, &SignalingAgent::Init_m, thread),
|
||||
NS_DISPATCH_SYNC);
|
||||
|
||||
ASSERT_TRUE_WAIT(sipcc_state() == sipcc::PeerConnectionImpl::kStarted,
|
||||
kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(ice_state() == sipcc::PeerConnectionImpl::kIceWaiting, 5000);
|
||||
@ -1808,6 +1821,13 @@ int main(int argc, char **argv) {
|
||||
|
||||
::testing::AddGlobalTestEnvironment(new test::SignalingEnvironment);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
// Because we don't initialize on the main thread, we can't register for
|
||||
// XPCOM shutdown callbacks (where the context is usually shut down) --
|
||||
// so we need to explictly destroy the context.
|
||||
sipcc::PeerConnectionCtx::Destroy();
|
||||
delete test_utils;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user