@@ -183,6 +183,9 @@ MediaTrackGraphImpl::~MediaTrackGraphImpl() {
183183 MOZ_ASSERT (mTracks .IsEmpty () && mSuspendedTracks .IsEmpty (),
184184 " All tracks should have been destroyed by messages from the main "
185185 " thread" );
186+ MOZ_ASSERT (
187+ mDirectMessages .IsEmpty (),
188+ " All direct tasks should have been drained in the final iteration" );
186189 LOG (LogLevel::Debug, (" MediaTrackGraph {} destroyed" , fmt::ptr (this )));
187190 LOG (LogLevel::Debug, (" MediaTrackGraphImpl::~MediaTrackGraphImpl" ));
188191}
@@ -1251,14 +1254,7 @@ void MediaTrackGraphImpl::ProduceDataForTracksBlockByBlock(
12511254void MediaTrackGraphImpl::RunMessageAfterProcessing (
12521255 already_AddRefed<nsIRunnable> aMessage) {
12531256 MOZ_ASSERT (OnGraphThread ());
1254-
1255- if (mFrontMessageQueue .IsEmpty ()) {
1256- mFrontMessageQueue .AppendElement ();
1257- }
1258-
1259- // Only one block is used for messages from the graph thread.
1260- MOZ_ASSERT (mFrontMessageQueue .Length () == 1 );
1261- mFrontMessageQueue [0 ].mMessages .AppendElement (std::move (aMessage));
1257+ DispatchDirectTask (std::move (aMessage));
12621258}
12631259
12641260void MediaTrackGraphImpl::RunMessagesInQueue () {
@@ -1632,9 +1628,7 @@ auto MediaTrackGraphImpl::OneIterationImpl(
16321628
16331629 ProcessChunkMetadata (oldProcessedTime);
16341630
1635- // Process graph messages queued from RunMessageAfterProcessing() on this
1636- // thread during the iteration.
1637- RunMessagesInQueue ();
1631+ DrainDirectTasks ();
16381632
16391633 if (!UpdateMainThreadState ()) {
16401634 if (Switching ()) {
@@ -3597,8 +3591,9 @@ void MediaTrackGraph::ForceShutDown() {
35973591 graph->ForceShutDown ();
35983592}
35993593
3600- NS_IMPL_ISUPPORTS (MediaTrackGraphImpl, nsIMemoryReporter, nsIObserver,
3601- nsIThreadObserver, nsITimerCallback, nsINamed)
3594+ NS_IMPL_ISUPPORTS (MediaTrackGraphImpl, nsIDirectTaskDispatcher,
3595+ nsIMemoryReporter, nsIObserver, nsIThreadObserver,
3596+ nsITimerCallback, nsINamed)
36023597
36033598NS_IMETHODIMP
36043599MediaTrackGraphImpl::CollectReports (nsIHandleReportCallback* aHandleReport,
@@ -4377,6 +4372,42 @@ NS_IMETHODIMP
43774372MediaTrackGraphImpl::AfterProcessNextEvent (nsIThreadInternal*, bool ) {
43784373 return NS_OK ;
43794374}
4375+
4376+ // nsIDirectTaskDispatcher methods
4377+
4378+ NS_IMETHODIMP
4379+ MediaTrackGraphImpl::DispatchDirectTask (already_AddRefed<nsIRunnable> aTask) {
4380+ MOZ_ASSERT (OnGraphThread ());
4381+ nsCOMPtr task = aTask;
4382+ PROFILER_MARKER (" MediaTrackGraphImpl::DispatchDirectTask" , OTHER ,
4383+ {MarkerStack::Capture ()}, FlowMarker,
4384+ Flow::FromPointer (task.get ()));
4385+ mDirectMessages .AppendElement (task.forget ());
4386+ return NS_OK ;
4387+ }
4388+
4389+ NS_IMETHODIMP
4390+ MediaTrackGraphImpl::DrainDirectTasks () {
4391+ MOZ_ASSERT (OnGraphThread ());
4392+ // Run all tasks in mDirectMessages. This continues even if one direct task
4393+ // adds another.
4394+ for (size_t i = 0 ; i < mDirectMessages .Length (); ++i) {
4395+ nsCOMPtr<nsIRunnable> message = std::move (mDirectMessages [i]);
4396+ AUTO_PROFILE_FOLLOWING_RUNNABLE (message);
4397+ message->Run ();
4398+ }
4399+ mDirectMessages .ClearAndRetainStorage ();
4400+ return NS_OK ;
4401+ }
4402+
4403+ NS_IMETHODIMP
4404+ MediaTrackGraphImpl::HaveDirectTasks (bool * aResult) {
4405+ if (!OnGraphThread ()) {
4406+ return NS_ERROR_FAILURE ;
4407+ }
4408+ *aResult = !mDirectMessages .IsEmpty ();
4409+ return NS_OK ;
4410+ }
43804411} // namespace mozilla
43814412
43824413#undef LOG
0 commit comments