From 139a3037ef983747d1b079007f73c440d27f73e2 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Fri, 25 Oct 2013 12:07:29 +1300 Subject: [PATCH] b=923301 add MediaStreamGraph::RunAfterPendingUpdates() r=roc --HG-- extra : transplant_source : %89%21%AE%87%C7%9C%07%28%3D%60T%83%16n%DC%C9O%87iy --- content/media/MediaStreamGraph.cpp | 34 ++++++++++++++++++++++++++++ content/media/MediaStreamGraph.h | 14 ++++++++++++ content/media/MediaStreamGraphImpl.h | 4 ++-- 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index 3e5b645c23c..6d272d82c27 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -1919,6 +1919,40 @@ MediaStream::RemoveListener(MediaStreamListener* aListener) } } +void +MediaStream::RunAfterPendingUpdates(nsRefPtr aRunnable) +{ + MOZ_ASSERT(NS_IsMainThread()); + MediaStreamGraphImpl* graph = GraphImpl(); + + // Special case when a non-realtime graph has not started, to ensure the + // runnable will run in finite time. + if (!(graph->mRealtime || graph->mNonRealtimeProcessing)) { + aRunnable->Run(); + } + + class Message : public ControlMessage { + public: + explicit Message(MediaStream* aStream, + already_AddRefed aRunnable) + : ControlMessage(aStream) + , mRunnable(aRunnable) {} + virtual void Run() MOZ_OVERRIDE + { + mStream->Graph()-> + DispatchToMainThreadAfterStreamStateUpdate(mRunnable.forget()); + } + virtual void RunDuringShutdown() MOZ_OVERRIDE + { + mRunnable->Run(); + } + private: + nsRefPtr mRunnable; + }; + + graph->AppendMessage(new Message(this, aRunnable.forget())); +} + void MediaStream::SetTrackEnabledImpl(TrackID aTrackID, bool aEnabled) { diff --git a/content/media/MediaStreamGraph.h b/content/media/MediaStreamGraph.h index ccf17360801..3287edac205 100644 --- a/content/media/MediaStreamGraph.h +++ b/content/media/MediaStreamGraph.h @@ -346,6 +346,20 @@ public: NS_ASSERTION(NS_IsMainThread(), "Call only on main thread"); mMainThreadListeners.RemoveElement(aListener); } + /** + * Ensure a runnable will run on the main thread after running all pending + * updates that were sent from the graph thread or will be sent before the + * graph thread receives the next graph update. + * + * If the graph has been shutdown or destroyed, or if it is non-realtime + * and has not started, then the runnable will be run + * synchronously/immediately. (There are no pending updates in these + * situations.) + * + * Main thread only. + */ + void RunAfterPendingUpdates(nsRefPtr aRunnable); + // Signal that the client is done with this MediaStream. It will be deleted later. virtual void Destroy(); // Returns the main-thread's view of how much data has been processed by diff --git a/content/media/MediaStreamGraphImpl.h b/content/media/MediaStreamGraphImpl.h index 135b3fb31b5..c7d2e8721b2 100644 --- a/content/media/MediaStreamGraphImpl.h +++ b/content/media/MediaStreamGraphImpl.h @@ -72,11 +72,11 @@ struct StreamUpdate { /** * This represents a message passed from the main thread to the graph thread. - * A ControlMessage always references a particular affected stream. + * A ControlMessage always has a weak reference a particular affected stream. */ class ControlMessage { public: - ControlMessage(MediaStream* aStream) : mStream(aStream) + explicit ControlMessage(MediaStream* aStream) : mStream(aStream) { MOZ_COUNT_CTOR(ControlMessage); }