diff --git a/dom/media/MediaEventSource.h b/dom/media/MediaEventSource.h index 5cda20900b49..8115ffa7c936 100644 --- a/dom/media/MediaEventSource.h +++ b/dom/media/MediaEventSource.h @@ -540,8 +540,6 @@ class MediaEventForwarder : public MediaEventSource { template using ArgType = typename detail::EventTypeTraits::ArgType; - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEventForwarder); - explicit MediaEventForwarder(nsCOMPtr aEventTarget) : mEventTarget(std::move(aEventTarget)) {} @@ -549,6 +547,8 @@ class MediaEventForwarder : public MediaEventSource { : mEventTarget(aOther.mEventTarget), mListeners(std::move(aOther.mListeners)) {} + ~MediaEventForwarder() { MOZ_ASSERT(mListeners.IsEmpty()); } + MediaEventForwarder& operator=(MediaEventForwarder&& aOther) { MOZ_RELEASE_ASSERT(mEventTarget == aOther.mEventTarget); MOZ_ASSERT(mListeners.IsEmpty()); @@ -556,10 +556,11 @@ class MediaEventForwarder : public MediaEventSource { } void Forward(MediaEventSource& aSource) { - mListeners.AppendElement(aSource.Connect( - mEventTarget, - [self = RefPtr(this)](ArgType&&... aEvents) { - self->NotifyInternal(std::forward...>(aEvents)...); + // Forwarding a rawptr `this` here is fine, since DisconnectAll disconnect + // all mListeners synchronously and prevents this handler from running. + mListeners.AppendElement( + aSource.Connect(mEventTarget, [this](ArgType&&... aEvents) { + this->NotifyInternal(std::forward...>(aEvents)...); })); } @@ -571,8 +572,6 @@ class MediaEventForwarder : public MediaEventSource { } private: - ~MediaEventForwarder() { MOZ_ASSERT(mListeners.IsEmpty()); } - const nsCOMPtr mEventTarget; nsTArray mListeners; }; diff --git a/dom/media/systemservices/MediaUtils.cpp b/dom/media/systemservices/MediaUtils.cpp index eaa81a4cb1a6..fc72b0699a2a 100644 --- a/dom/media/systemservices/MediaUtils.cpp +++ b/dom/media/systemservices/MediaUtils.cpp @@ -56,32 +56,31 @@ class MediaEventBlocker : public ShutdownBlocker { class RefCountedTicket { RefPtr mBlocker; - RefPtr> mShutdownEventForwarder; + MediaEventForwarder mShutdownEventForwarder; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedTicket) RefCountedTicket() - : mShutdownEventForwarder( - new MediaEventForwarder(GetMainThreadSerialEventTarget())) {} + : mShutdownEventForwarder(GetMainThreadSerialEventTarget()) {} void AddBlocker(const nsString& aName, const nsString& aFileName, int32_t aLineNr) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mBlocker); mBlocker = MakeAndAddRef(aName); - mShutdownEventForwarder->Forward(mBlocker->ShutdownEvent()); + mShutdownEventForwarder.Forward(mBlocker->ShutdownEvent()); GetShutdownBarrier()->AddBlocker(mBlocker.get(), aFileName, aLineNr, aName); } - MediaEventSource& ShutdownEvent() { return *mShutdownEventForwarder; } + MediaEventSource& ShutdownEvent() { return mShutdownEventForwarder; } protected: virtual ~RefCountedTicket() { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mBlocker); GetShutdownBarrier()->RemoveBlocker(mBlocker.get()); - mShutdownEventForwarder->DisconnectAll(); + mShutdownEventForwarder.DisconnectAll(); } }; diff --git a/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.cpp b/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.cpp index 3d9edf41f6f6..d5a9e1f54242 100644 --- a/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.cpp +++ b/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.cpp @@ -35,8 +35,8 @@ WebrtcVideoDecoderFactory::CreateVideoDecoder( case webrtc::VideoCodecType::kVideoCodecH264: { // Get an external decoder auto gmpDecoder = WrapUnique(GmpVideoCodec::CreateDecoder(mPCHandle)); - mCreatedGmpPluginEvent->Forward(*gmpDecoder->InitPluginEvent()); - mReleasedGmpPluginEvent->Forward(*gmpDecoder->ReleasePluginEvent()); + mCreatedGmpPluginEvent.Forward(*gmpDecoder->InitPluginEvent()); + mReleasedGmpPluginEvent.Forward(*gmpDecoder->ReleasePluginEvent()); decoder.reset(gmpDecoder.release()); break; } @@ -103,8 +103,8 @@ WebrtcVideoEncoderFactory::InternalFactory::CreateVideoEncoder( case webrtc::VideoCodecType::kVideoCodecH264: { // get an external encoder auto gmpEncoder = WrapUnique(GmpVideoCodec::CreateEncoder(mPCHandle)); - mCreatedGmpPluginEvent->Forward(*gmpEncoder->InitPluginEvent()); - mReleasedGmpPluginEvent->Forward(*gmpEncoder->ReleasePluginEvent()); + mCreatedGmpPluginEvent.Forward(*gmpEncoder->InitPluginEvent()); + mReleasedGmpPluginEvent.Forward(*gmpEncoder->ReleasePluginEvent()); encoder.reset(gmpEncoder.release()); break; } diff --git a/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.h b/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.h index a02d132b75f5..3fd91c6954a0 100644 --- a/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.h +++ b/dom/media/webrtc/libwebrtcglue/WebrtcVideoCodecFactory.h @@ -20,30 +20,28 @@ class GmpPluginNotifier : public GmpPluginNotifierInterface { public: explicit GmpPluginNotifier(nsCOMPtr aOwningThread) : mOwningThread(std::move(aOwningThread)), - mCreatedGmpPluginEvent( - new MediaEventForwarder(mOwningThread)), - mReleasedGmpPluginEvent( - new MediaEventForwarder(mOwningThread)) {} + mCreatedGmpPluginEvent(mOwningThread), + mReleasedGmpPluginEvent(mOwningThread) {} ~GmpPluginNotifier() { - mCreatedGmpPluginEvent->DisconnectAll(); - mReleasedGmpPluginEvent->DisconnectAll(); + mCreatedGmpPluginEvent.DisconnectAll(); + mReleasedGmpPluginEvent.DisconnectAll(); } MediaEventSource& CreatedGmpPluginEvent() override { MOZ_ASSERT(mOwningThread->IsOnCurrentThread()); - return *mCreatedGmpPluginEvent; + return mCreatedGmpPluginEvent; } MediaEventSource& ReleasedGmpPluginEvent() override { MOZ_ASSERT(mOwningThread->IsOnCurrentThread()); - return *mReleasedGmpPluginEvent; + return mReleasedGmpPluginEvent; } protected: const nsCOMPtr mOwningThread; - RefPtr> mCreatedGmpPluginEvent; - RefPtr> mReleasedGmpPluginEvent; + MediaEventForwarder mCreatedGmpPluginEvent; + MediaEventForwarder mReleasedGmpPluginEvent; }; class WebrtcVideoDecoderFactory : public GmpPluginNotifier,