Bug 1208378 - Store MediaStreamTrackSource::Sink in a WeakPtr. r=jib
authorAndreas Pehrson <pehrsons@mozilla.com>
Mon, 06 Nov 2017 18:04:27 +0100
changeset 437308 83d5a772d5b46603451f8589d48fead0c8bc5967
parent 437307 05fc5e9fd820bbf6489429dee9c5b5e7cbad6b63
child 437309 29b6b2c4855d593f457326d6c81c56e47a5dd22f
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersjib
bugs1208378
milestone59.0a1
Bug 1208378 - Store MediaStreamTrackSource::Sink in a WeakPtr. r=jib MozReview-Commit-ID: Movk15KRK7
dom/media/MediaStreamTrack.h
--- a/dom/media/MediaStreamTrack.h
+++ b/dom/media/MediaStreamTrack.h
@@ -52,19 +52,20 @@ enum class CallerType : uint32_t;
  * sharing this source.
  */
 class MediaStreamTrackSource : public nsISupports
 {
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackSource)
 
 public:
-  class Sink
+  class Sink : public SupportsWeakPtr<Sink>
   {
   public:
+    MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MediaStreamTrackSource::Sink)
     virtual void PrincipalChanged() = 0;
   };
 
   MediaStreamTrackSource(nsIPrincipal* aPrincipal,
                          const nsString& aLabel)
     : mPrincipal(aPrincipal),
       mLabel(aLabel),
       mStopped(false)
@@ -145,25 +146,31 @@ public:
    */
   void RegisterSink(Sink* aSink)
   {
     MOZ_ASSERT(NS_IsMainThread());
     if (mStopped) {
       return;
     }
     mSinks.AppendElement(aSink);
+    while(mSinks.RemoveElement(nullptr)) {
+      MOZ_ASSERT_UNREACHABLE("Sink was not explicitly removed");
+    }
   }
 
   /**
    * Called by each MediaStreamTrack clone on Stop() if supported by the
    * source (us) or destruction.
    */
   void UnregisterSink(Sink* aSink)
   {
     MOZ_ASSERT(NS_IsMainThread());
+    while(mSinks.RemoveElement(nullptr)) {
+      MOZ_ASSERT_UNREACHABLE("Sink was not explicitly removed");
+    }
     if (mSinks.RemoveElement(aSink) && mSinks.IsEmpty()) {
       MOZ_ASSERT(!mStopped);
       Stop();
       mStopped = true;
     }
   }
 
 protected:
@@ -172,26 +179,33 @@ protected:
   }
 
   /**
    * Called by a sub class when the principal has changed.
    * Notifies all sinks.
    */
   void PrincipalChanged()
   {
-    for (Sink* sink : mSinks) {
+    MOZ_ASSERT(NS_IsMainThread());
+    nsTArray<WeakPtr<Sink>> sinks(mSinks);
+    for (auto& sink : sinks) {
+      if (!sink) {
+        MOZ_ASSERT_UNREACHABLE("Sink was not explicitly removed");
+        mSinks.RemoveElement(sink);
+        continue;
+      }
       sink->PrincipalChanged();
     }
   }
 
   // Principal identifying who may access the contents of this source.
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   // Currently registered sinks.
-  nsTArray<Sink*> mSinks;
+  nsTArray<WeakPtr<Sink>> mSinks;
 
   // The label of the track we are the source of per the MediaStreamTrack spec.
   const nsString mLabel;
 
   // True if all MediaStreamTrack users have unregistered from this source and
   // Stop() has been called.
   bool mStopped;
 };