Bug 1322274: Make internal pc._legacyCatchAndCloseGuard responsible for checking closed state.
MozReview-Commit-ID: LYS2pjg9GEv
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -503,17 +503,16 @@ RTCPeerConnection.prototype = {
let idpTimeout = Services.prefs.getIntPref(prefName);
this._localIdp = new PeerConnectionIdp(this._win, idpTimeout);
this._remoteIdp = new PeerConnectionIdp(this._win, idpTimeout);
},
// Add a function to the internal operations chain.
_chain: function(func) {
- this._checkClosed(); // out here DOMException line-numbers work.
let p = this._operationsChain.then(() => {
// Don't _checkClosed() inside the chain, because it throws, and spec
// behavior as of this writing is to NOT reject outstanding promises on
// close. This is what happens most of the time anyways, as the c++ code
// stops calling us once closed, hanging the chain. However, c++ may
// already have queued tasks on us, so if we're one of those then sit back.
if (!this._closed) {
return func();
@@ -526,23 +525,28 @@ RTCPeerConnection.prototype = {
// This wrapper helps implement legacy callbacks in a manner that produces
// correct line-numbers in errors, provided that methods validate their inputs
// before putting themselves on the pc's operations chain.
//
// It also serves as guard against settling promises past close().
_legacyCatchAndCloseGuard: function(onSuccess, onError, func) {
+ let operation = () => {
+ this._checkClosed();
+ return func();
+ };
+
if (!onSuccess) {
- return this._win.Promise.resolve(func())
+ return this._win.Promise.resolve(operation())
.then(v => (this._closed ? new Promise(() => {}) : v),
e => (this._closed ? new Promise(() => {}) : Promise.reject(e)));
}
try {
- return this._win.Promise.resolve(func())
+ return this._win.Promise.resolve(operation())
.then(this._wrapLegacyCallback(onSuccess),
this._wrapLegacyCallback(onError));
} catch (e) {
this._wrapLegacyCallback(onError)(e);
return this._win.Promise.resolve(); // avoid webidl TypeError
}
},
@@ -945,16 +949,17 @@ RTCPeerConnection.prototype = {
},
setIdentityProvider: function(provider, protocol, username) {
this._checkClosed();
this._localIdp.setIdentityProvider(provider, protocol, username);
},
getIdentityAssertion: function() {
+ this._checkClosed();
let origin = Cu.getWebIDLCallerPrincipal().origin;
return this._chain(
() => this._certificateReady.then(
() => this._localIdp.getIdentityAssertion(this._impl.fingerprint, origin)
)
);
},
@@ -1618,16 +1623,17 @@ function RTCRtpSender(pc, track, stream)
}
RTCRtpSender.prototype = {
classDescription: "RTCRtpSender",
classID: PC_SENDER_CID,
contractID: PC_SENDER_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
replaceTrack: function(withTrack) {
+ this._pc._checkClosed();
return this._pc._chain(() => this._pc._replaceTrack(this, withTrack));
},
setParameters: function(parameters) {
return this._pc._win.Promise.resolve()
.then(() => this._pc._setParameters(this, parameters));
},