Bug 1407542 - Remove back reference to consumer in MediaStreamTrack. r=jib,smaug

It doesn't matter that this is traversed by the cycle collector when the track is live and playing.
It prevents cycle collection of any number of MediaStreams that contain (thus consume) this track.

MozReview-Commit-ID: GvdLfWDTVQQ

--HG--
extra : rebase_source : 29e65d25bd7cdf03e32ff4aa736b0ff762ebf1c1
This commit is contained in:
Andreas Pehrson 2017-10-10 20:48:58 +02:00
Родитель a0b90be9da
Коммит 368e21e1b1
3 изменённых файлов: 28 добавлений и 33 удалений

Просмотреть файл

@ -341,9 +341,8 @@ public:
explicit PlaybackTrackListener(DOMMediaStream* aStream) : explicit PlaybackTrackListener(DOMMediaStream* aStream) :
mStream(aStream) {} mStream(aStream) {}
NS_DECL_ISUPPORTS_INHERITED NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PlaybackTrackListener)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaybackTrackListener, NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PlaybackTrackListener)
MediaStreamTrackConsumer)
void NotifyEnded(MediaStreamTrack* aTrack) override void NotifyEnded(MediaStreamTrack* aTrack) override
{ {
@ -367,15 +366,9 @@ protected:
RefPtr<DOMMediaStream> mStream; RefPtr<DOMMediaStream> mStream;
}; };
NS_IMPL_ADDREF_INHERITED(DOMMediaStream::PlaybackTrackListener, NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(DOMMediaStream::PlaybackTrackListener, AddRef)
MediaStreamTrackConsumer) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMediaStream::PlaybackTrackListener, Release)
NS_IMPL_RELEASE_INHERITED(DOMMediaStream::PlaybackTrackListener, NS_IMPL_CYCLE_COLLECTION(DOMMediaStream::PlaybackTrackListener, mStream)
MediaStreamTrackConsumer)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMMediaStream::PlaybackTrackListener)
NS_INTERFACE_MAP_END_INHERITING(MediaStreamTrackConsumer)
NS_IMPL_CYCLE_COLLECTION_INHERITED(DOMMediaStream::PlaybackTrackListener,
MediaStreamTrackConsumer,
mStream)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMediaStream) NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMediaStream)

Просмотреть файл

@ -57,14 +57,6 @@ MediaStreamTrackSource::ApplyConstraints(
return p.forget(); return p.forget();
} }
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaStreamTrackConsumer)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaStreamTrackConsumer)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaStreamTrackConsumer)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_0(MediaStreamTrackConsumer)
/** /**
* PrincipalHandleListener monitors changes in PrincipalHandle of the media flowing * PrincipalHandleListener monitors changes in PrincipalHandle of the media flowing
* through the MediaStreamGraph. * through the MediaStreamGraph.
@ -187,7 +179,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(MediaStreamTrack)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaStreamTrack, NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaStreamTrack,
DOMEventTargetHelper) DOMEventTargetHelper)
tmp->Destroy(); tmp->Destroy();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsumers)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningStream) NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningStream)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource) NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalTrack) NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalTrack)
@ -197,7 +188,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaStreamTrack, NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaStreamTrack,
DOMEventTargetHelper) DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsumers)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningStream) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalTrack) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalTrack)
@ -379,10 +369,14 @@ MediaStreamTrack::NotifyEnded()
{ {
MOZ_ASSERT(mReadyState == MediaStreamTrackState::Ended); MOZ_ASSERT(mReadyState == MediaStreamTrackState::Ended);
for (int32_t i = mConsumers.Length() - 1; i >= 0; --i) { auto consumers(mConsumers);
// Loop backwards by index in case the consumer removes itself in the for (const auto& consumer : consumers) {
// callback. if (consumer) {
mConsumers[i]->NotifyEnded(this); consumer->NotifyEnded(this);
} else {
MOZ_ASSERT_UNREACHABLE("A consumer was not explicitly removed");
mConsumers.RemoveElement(consumer);
}
} }
} }
@ -405,12 +399,22 @@ MediaStreamTrack::AddConsumer(MediaStreamTrackConsumer* aConsumer)
{ {
MOZ_ASSERT(!mConsumers.Contains(aConsumer)); MOZ_ASSERT(!mConsumers.Contains(aConsumer));
mConsumers.AppendElement(aConsumer); mConsumers.AppendElement(aConsumer);
// Remove destroyed consumers for cleanliness
while (mConsumers.RemoveElement(nullptr)) {
MOZ_ASSERT_UNREACHABLE("A consumer was not explicitly removed");
}
} }
void void
MediaStreamTrack::RemoveConsumer(MediaStreamTrackConsumer* aConsumer) MediaStreamTrack::RemoveConsumer(MediaStreamTrackConsumer* aConsumer)
{ {
mConsumers.RemoveElement(aConsumer); mConsumers.RemoveElement(aConsumer);
// Remove destroyed consumers for cleanliness
while (mConsumers.RemoveElement(nullptr)) {
MOZ_ASSERT_UNREACHABLE("A consumer was not explicitly removed");
}
} }
already_AddRefed<MediaStreamTrack> already_AddRefed<MediaStreamTrack>

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/dom/MediaStreamTrackBinding.h" #include "mozilla/dom/MediaStreamTrackBinding.h"
#include "mozilla/dom/MediaTrackSettingsBinding.h" #include "mozilla/dom/MediaTrackSettingsBinding.h"
#include "mozilla/media/MediaUtils.h" #include "mozilla/media/MediaUtils.h"
#include "mozilla/WeakPtr.h"
#include "nsError.h" #include "nsError.h"
#include "nsID.h" #include "nsID.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
@ -221,11 +222,11 @@ protected:
* Base class that consumers of a MediaStreamTrack can use to get notifications * Base class that consumers of a MediaStreamTrack can use to get notifications
* about state changes in the track. * about state changes in the track.
*/ */
class MediaStreamTrackConsumer : public nsISupports class MediaStreamTrackConsumer
: public SupportsWeakPtr<MediaStreamTrackConsumer>
{ {
public: public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS MOZ_DECLARE_WEAKREFERENCE_TYPENAME(MediaStreamTrackConsumer)
NS_DECL_CYCLE_COLLECTION_CLASS(MediaStreamTrackConsumer)
/** /**
* Called when the track's readyState transitions to "ended". * Called when the track's readyState transitions to "ended".
@ -233,9 +234,6 @@ public:
* including MediaStreamTrack::Stop(). * including MediaStreamTrack::Stop().
*/ */
virtual void NotifyEnded(MediaStreamTrack* aTrack) {}; virtual void NotifyEnded(MediaStreamTrack* aTrack) {};
protected:
virtual ~MediaStreamTrackConsumer() {}
}; };
/** /**
@ -456,7 +454,7 @@ protected:
nsTArray<PrincipalChangeObserver<MediaStreamTrack>*> mPrincipalChangeObservers; nsTArray<PrincipalChangeObserver<MediaStreamTrack>*> mPrincipalChangeObservers;
nsTArray<RefPtr<MediaStreamTrackConsumer>> mConsumers; nsTArray<WeakPtr<MediaStreamTrackConsumer>> mConsumers;
RefPtr<DOMMediaStream> mOwningStream; RefPtr<DOMMediaStream> mOwningStream;
TrackID mTrackID; TrackID mTrackID;