mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 812886: Watch network (tear)down events and kill PeerConnections r=ekr,smaug,bsmith
This commit is contained in:
parent
208ddd52f5
commit
645ded6229
@ -22,8 +22,10 @@ const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
|
||||
// Global list of PeerConnection objects, so they can be cleaned up when
|
||||
// a page is torn down. (Maps inner window ID to an array of PC objects).
|
||||
function GlobalPCList() {
|
||||
this._list = {};
|
||||
this._list = [];
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", true);
|
||||
Services.obs.addObserver(this, "profile-change-net-teardown", true);
|
||||
Services.obs.addObserver(this, "network:offline-about-to-go-offline", true);
|
||||
}
|
||||
GlobalPCList.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
@ -63,19 +65,32 @@ GlobalPCList.prototype = {
|
||||
},
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic != "inner-window-destroyed") {
|
||||
return;
|
||||
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;
|
||||
});
|
||||
delete this._list[winID];
|
||||
}
|
||||
} else if (topic == "profile-change-net-teardown" ||
|
||||
topic == "network:offline-about-to-go-offline") {
|
||||
// Delete all peerconnections on shutdown - synchronously (we need
|
||||
// them to be done deleting transports before we return)!
|
||||
// Also kill them if "Work Offline" is selected - more can be created
|
||||
// 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;
|
||||
});
|
||||
};
|
||||
}
|
||||
let winID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (this._list[winID]) {
|
||||
this._list[winID].forEach(function(pc) {
|
||||
pc._pc.close();
|
||||
delete pc._observer;
|
||||
pc._pc = null;
|
||||
});
|
||||
delete this._list[winID];
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
let _globalPCList = new GlobalPCList();
|
||||
|
||||
@ -453,7 +468,7 @@ PeerConnection.prototype = {
|
||||
close: function() {
|
||||
this._queueOrRun({
|
||||
func: this._pc.close,
|
||||
args: [],
|
||||
args: [false],
|
||||
wait: false
|
||||
});
|
||||
this._closed = true;
|
||||
|
@ -65,7 +65,7 @@ interface IPeerConnectionObserver : nsISupports
|
||||
void foundIceCandidate(in string candidate);
|
||||
};
|
||||
|
||||
[scriptable, uuid(f6819246-f5af-40f2-ab82-e166d5da7ba0)]
|
||||
[scriptable, uuid(c86903c7-0a2e-42b4-903c-1518f03b9ba5)]
|
||||
interface IPeerConnection : nsISupports
|
||||
{
|
||||
const unsigned long kHintAudio = 0x00000001;
|
||||
@ -113,7 +113,7 @@ interface IPeerConnection : nsISupports
|
||||
void addIceCandidate(in string candidate, in string mid, in unsigned short level);
|
||||
|
||||
/* Puts the SIPCC engine back to 'kIdle', shuts down threads, deletes state */
|
||||
void close();
|
||||
void close(in bool isSynchronous);
|
||||
|
||||
/* Attributes */
|
||||
readonly attribute string localDescription;
|
||||
|
@ -278,7 +278,7 @@ PeerConnectionImpl::PeerConnectionImpl()
|
||||
|
||||
PeerConnectionImpl::~PeerConnectionImpl()
|
||||
{
|
||||
Close();
|
||||
Close(false);
|
||||
// Since this and Initialize() occur on MainThread, they can't both be
|
||||
// running at once
|
||||
// Might be more optimal to release off a timer (and XPCOM Shutdown)
|
||||
@ -935,7 +935,7 @@ PeerConnectionImpl::GetIceState(uint32_t* aState)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::Close()
|
||||
PeerConnectionImpl::Close(bool aIsSynchronous)
|
||||
{
|
||||
if (mCall != NULL)
|
||||
mCall->endCall();
|
||||
@ -944,7 +944,7 @@ PeerConnectionImpl::Close()
|
||||
mDataConnection->CloseAll();
|
||||
#endif
|
||||
|
||||
ShutdownMedia();
|
||||
ShutdownMedia(aIsSynchronous);
|
||||
|
||||
// DataConnection will need to stay alive until all threads/runnables exit
|
||||
|
||||
@ -952,7 +952,7 @@ PeerConnectionImpl::Close()
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionImpl::ShutdownMedia()
|
||||
PeerConnectionImpl::ShutdownMedia(bool aIsSynchronous)
|
||||
{
|
||||
// Check that we are on the main thread.
|
||||
if (mThread) {
|
||||
@ -969,10 +969,15 @@ PeerConnectionImpl::ShutdownMedia()
|
||||
// This avoids reentrancy issues with the garbage collector.
|
||||
// Note that no media calls may be made after this point
|
||||
// because we have removed the pointer.
|
||||
// For the aIsSynchronous case, we *know* the PeerConnection is
|
||||
// still alive, and are shutting it down on network teardown/etc, so
|
||||
// recursive GC isn't an issue. (Recursive GC should assert)
|
||||
|
||||
// Forget the reference so that we can transfer it to
|
||||
// SelfDestruct().
|
||||
RUN_ON_THREAD(mThread, WrapRunnable(mMedia.forget().get(),
|
||||
&PeerConnectionMedia::SelfDestruct), NS_DISPATCH_NORMAL);
|
||||
&PeerConnectionMedia::SelfDestruct),
|
||||
aIsSynchronous ? NS_DISPATCH_SYNC : NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -166,7 +166,7 @@ private:
|
||||
}
|
||||
|
||||
// Shut down media. Called on any thread.
|
||||
void ShutdownMedia();
|
||||
void ShutdownMedia(bool isSynchronous);
|
||||
|
||||
nsresult MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aStream);
|
||||
nsresult MakeRemoteSource(nsDOMMediaStream* aStream, RemoteSourceStreamInfo** aInfo);
|
||||
|
Loading…
Reference in New Issue
Block a user