Bug 1574965 - Remove a graph that becomes empty from gGraphs synchronously. r=karlt,padenot

This gives control of the graph's lifetime to main thread. Not being in gGraphs
means it's not meant to be used for any new streams as it will irreversibly be
shutting down.

This obsoletes GraphDriver::Revive.

Differential Revision: https://phabricator.services.mozilla.com/D43663

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andreas Pehrson 2019-08-29 12:49:43 +00:00
Родитель 973268af17
Коммит 87b3c4b78a
2 изменённых файлов: 32 добавлений и 18 удалений

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

@ -1674,16 +1674,6 @@ void MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG) {
nsCOMPtr<nsIRunnable> event =
new MediaStreamGraphShutDownRunnable(this);
mAbstractMainThread->Dispatch(event.forget());
LOG(LogLevel::Debug, ("%p: Disconnecting MediaStreamGraph", this));
// Find the graph in the hash table and remove it.
for (auto iter = gGraphs.Iter(); !iter.Done(); iter.Next()) {
if (iter.UserData() == this) {
iter.Remove();
break;
}
}
}
} else {
if (LifecycleStateRef() <= LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
@ -1837,14 +1827,6 @@ void MediaStreamGraphImpl::AppendMessage(UniquePtr<ControlMessage> aMessage) {
#endif
if (IsEmpty() &&
LifecycleStateRef() >= LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION) {
// Find the graph in the hash table and remove it.
for (auto iter = gGraphs.Iter(); !iter.Done(); iter.Next()) {
if (iter.UserData() == this) {
iter.Remove();
break;
}
}
Destroy();
}
return;
@ -2033,6 +2015,7 @@ void MediaStream::Destroy() {
}
void RunDuringShutdown() override { Run(); }
};
GraphImpl()->RemoveStream(this);
GraphImpl()->AppendMessage(MakeUnique<Message>(this));
// Message::RunDuringShutdown may have removed this stream from the graph,
// but our kungFuDeathGrip above will have kept this stream alive if
@ -3544,9 +3527,27 @@ void MediaStreamGraph::AddStream(MediaStream* aStream) {
#endif
NS_ADDREF(aStream);
aStream->SetGraphImpl(graph);
++graph->mMainThreadStreamCount;
graph->AppendMessage(MakeUnique<CreateMessage>(aStream));
}
void MediaStreamGraphImpl::RemoveStream(MediaStream* aStream) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(mMainThreadStreamCount > 0);
if (--mMainThreadStreamCount == 0) {
LOG(LogLevel::Info, ("MediaStreamGraph %p, last stream %p removed from "
"main thread. Graph will shut down.",
this, aStream));
// Find the graph in the hash table and remove it.
for (auto iter = gGraphs.Iter(); !iter.Done(); iter.Next()) {
if (iter.UserData() == this) {
iter.Remove();
break;
}
}
}
}
class GraphStartedRunnable final : public Runnable {
public:
GraphStartedRunnable(AudioNodeStream* aStream, MediaStreamGraph* aGraph)

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

@ -441,6 +441,10 @@ class MediaStreamGraphImpl : public MediaStreamGraph,
* stream back to the main thread are flushed.
*/
void RemoveStreamGraphThread(MediaStream* aStream);
/**
* Remove a stream from the graph. Main thread.
*/
void RemoveStream(MediaStream* aStream);
/**
* Remove aPort from the graph and release it.
*/
@ -649,6 +653,15 @@ class MediaStreamGraphImpl : public MediaStreamGraph,
*/
const UniquePtr<GraphRunner> mGraphRunner;
/**
* Main-thread view of the number of streams in this graph, for lifetime
* management.
*
* When this becomes zero, the graph is marked as forbidden to add more
* streams to. It will be shut down shortly after.
*/
size_t mMainThreadStreamCount = 0;
/**
* Graphs own owning references to their driver, until shutdown. When a driver
* switch occur, previous driver is either deleted, or it's ownership is