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) :
mStream(aStream) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PlaybackTrackListener,
MediaStreamTrackConsumer)
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(PlaybackTrackListener)
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(PlaybackTrackListener)
void NotifyEnded(MediaStreamTrack* aTrack) override
{
@ -367,15 +366,9 @@ protected:
RefPtr<DOMMediaStream> mStream;
};
NS_IMPL_ADDREF_INHERITED(DOMMediaStream::PlaybackTrackListener,
MediaStreamTrackConsumer)
NS_IMPL_RELEASE_INHERITED(DOMMediaStream::PlaybackTrackListener,
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_ROOT_NATIVE(DOMMediaStream::PlaybackTrackListener, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(DOMMediaStream::PlaybackTrackListener, Release)
NS_IMPL_CYCLE_COLLECTION(DOMMediaStream::PlaybackTrackListener, mStream)
NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMediaStream)

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

@ -57,14 +57,6 @@ MediaStreamTrackSource::ApplyConstraints(
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
* through the MediaStreamGraph.
@ -187,7 +179,6 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(MediaStreamTrack)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaStreamTrack,
DOMEventTargetHelper)
tmp->Destroy();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mConsumers)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwningStream)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginalTrack)
@ -197,7 +188,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaStreamTrack,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mConsumers)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwningStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalTrack)
@ -379,10 +369,14 @@ MediaStreamTrack::NotifyEnded()
{
MOZ_ASSERT(mReadyState == MediaStreamTrackState::Ended);
for (int32_t i = mConsumers.Length() - 1; i >= 0; --i) {
// Loop backwards by index in case the consumer removes itself in the
// callback.
mConsumers[i]->NotifyEnded(this);
auto consumers(mConsumers);
for (const auto& consumer : consumers) {
if (consumer) {
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));
mConsumers.AppendElement(aConsumer);
// Remove destroyed consumers for cleanliness
while (mConsumers.RemoveElement(nullptr)) {
MOZ_ASSERT_UNREACHABLE("A consumer was not explicitly removed");
}
}
void
MediaStreamTrack::RemoveConsumer(MediaStreamTrackConsumer* 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>

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

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