From 1bffbe178b6d138e323fbec6184dbcf62bae28c9 Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Tue, 5 Jan 2016 10:16:22 +0800 Subject: [PATCH] Bug 1208371 - Count the users of a MediaStream to ease Destroy() responsibility. r=roc MozReview-Commit-ID: FdcR4ChTND4 --HG-- extra : rebase_source : c0dfccffb686b483203b2906b734ae8b9459b924 --- dom/media/MediaStreamGraph.cpp | 23 +++++++++++++++++++++++ dom/media/MediaStreamGraph.h | 14 +++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dom/media/MediaStreamGraph.cpp b/dom/media/MediaStreamGraph.cpp index 4142d61e128c..fc07235e8ea7 100644 --- a/dom/media/MediaStreamGraph.cpp +++ b/dom/media/MediaStreamGraph.cpp @@ -1839,6 +1839,7 @@ MediaStream::MediaStream(DOMMediaStream* aWrapper) , mMainThreadFinished(false) , mFinishedNotificationSent(false) , mMainThreadDestroyed(false) + , mNrOfMainThreadUsers(0) , mGraph(nullptr) , mAudioChannelType(dom::AudioChannel::Normal) { @@ -1982,6 +1983,8 @@ MediaStream::DestroyImpl() void MediaStream::Destroy() { + NS_ASSERTION(mNrOfMainThreadUsers == 0, + "Do not mix Destroy() and RegisterUser()/UnregisterUser()"); // Keep this stream alive until we leave this method RefPtr kungFuDeathGrip = this; @@ -2006,6 +2009,26 @@ MediaStream::Destroy() mMainThreadDestroyed = true; } +void +MediaStream::RegisterUser() +{ + MOZ_ASSERT(NS_IsMainThread()); + ++mNrOfMainThreadUsers; +} + +void +MediaStream::UnregisterUser() +{ + MOZ_ASSERT(NS_IsMainThread()); + + --mNrOfMainThreadUsers; + NS_ASSERTION(mNrOfMainThreadUsers >= 0, "Double-removal of main thread user"); + NS_ASSERTION(!IsDestroyed(), "Do not mix Destroy() and RegisterUser()/UnregisterUser()"); + if (mNrOfMainThreadUsers == 0) { + Destroy(); + } +} + void MediaStream::AddAudioOutput(void* aKey) { diff --git a/dom/media/MediaStreamGraph.h b/dom/media/MediaStreamGraph.h index 964d45282134..aab74a9b94d6 100644 --- a/dom/media/MediaStreamGraph.h +++ b/dom/media/MediaStreamGraph.h @@ -431,8 +431,19 @@ public: */ void RunAfterPendingUpdates(already_AddRefed aRunnable); - // Signal that the client is done with this MediaStream. It will be deleted later. + // Signal that the client is done with this MediaStream. It will be deleted + // later. Do not mix usage of Destroy() with RegisterUser()/UnregisterUser(). + // That will cause the MediaStream to be destroyed twice, which will cause + // some assertions to fail. virtual void Destroy(); + // Signal that a client is using this MediaStream. Useful to not have to + // explicitly manage ownership (responsibility to Destroy()) when there are + // multiple clients using a MediaStream. + void RegisterUser(); + // Signal that a client no longer needs this MediaStream. When the number of + // clients using this MediaStream reaches 0, it will be destroyed. + void UnregisterUser(); + // Returns the main-thread's view of how much data has been processed by // this stream. StreamTime GetCurrentTime() @@ -706,6 +717,7 @@ protected: bool mMainThreadFinished; bool mFinishedNotificationSent; bool mMainThreadDestroyed; + int mNrOfMainThreadUsers; // Our media stream graph. null if destroyed on the graph thread. MediaStreamGraphImpl* mGraph;