Bug 1322274: Make internal pc._legacyCatchAndCloseGuard responsible for checking closed state. draft
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 17 Nov 2016 01:56:26 -0500
changeset 448581 7f620a3ed22fd7f65603ff2cacff069e24143512
parent 448580 2f08f992e5018fc63cf080529f991b2630eab11a
child 448582 0b66ce022df1ae1428502b2e9a6ba77b9c6e637d
push id38366
push userjbruaroey@mozilla.com
push dateSun, 11 Dec 2016 01:26:04 +0000
bugs1322274
milestone53.0a1
Bug 1322274: Make internal pc._legacyCatchAndCloseGuard responsible for checking closed state. MozReview-Commit-ID: LYS2pjg9GEv
dom/media/PeerConnection.js
--- 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));
   },