Bug 1208378 - Store MediaStreamTrackSource::Sink in a WeakPtr. r?jib draft
authorAndreas Pehrson <pehrsons@mozilla.com>
Mon, 06 Nov 2017 18:04:27 +0100
changeset 695691 b68fb7efce74e63a1d04f292790e2975d62fca34
parent 692714 4ada8f0d5cc011af4bc0f4fadbb25ea3e1e62bfc
child 695692 002346b4c0df07e51c0afa5e7bb37a261eaca018
push id88502
push userbmo:apehrson@mozilla.com
push dateThu, 09 Nov 2017 17:30:09 +0000
reviewersjib
bugs1208378
milestone58.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
@@ -51,19 +51,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)
@@ -144,25 +145,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:
@@ -171,26 +178,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;
 };