b=914030 shut down an AudioDestinationNode's graph on destruction, if not already r=ehsan

This means that the graph will be shutdown properly, even if the
AudioDestinationNode is unlinked before AudioContext::Shutdown() is called.

Making MediaStreamGraph::DestroyNonRealtimeInstance() idempotent also makes
AudioContext::Shutdown() idempotent.

--HG--
extra : transplant_source : jZ%86%C5%C2n%17%EF%C2%C0y%ED%14%0E%17_dt%0C%07
This commit is contained in:
Karl Tomlinson 2013-09-10 17:05:22 +12:00
Родитель b5d291c0c7
Коммит dc411d889b
5 изменённых файлов: 29 добавлений и 2 удалений

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

@ -2352,9 +2352,12 @@ void
MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph) MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
{ {
NS_ASSERTION(NS_IsMainThread(), "Main thread only"); NS_ASSERTION(NS_IsMainThread(), "Main thread only");
MOZ_ASSERT(aGraph != gGraph, "Should not destroy the global graph here"); MOZ_ASSERT(aGraph->IsNonRealtime(), "Should not destroy the global graph here");
MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph); MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph);
if (graph->mForceShutDown)
return; // already done
if (!graph->mNonRealtimeProcessing) { if (!graph->mNonRealtimeProcessing) {
// Start the graph, but don't produce anything // Start the graph, but don't produce anything
graph->StartNonRealtimeProcessing(0); graph->StartNonRealtimeProcessing(0);
@ -2421,6 +2424,12 @@ MediaStreamGraph::CreateAudioNodeStream(AudioNodeEngine* aEngine,
return stream; return stream;
} }
bool
MediaStreamGraph::IsNonRealtime() const
{
return this != gGraph;
}
void void
MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess) MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess)
{ {

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

@ -975,6 +975,7 @@ public:
// Main thread only // Main thread only
static MediaStreamGraph* GetInstance(); static MediaStreamGraph* GetInstance();
static MediaStreamGraph* CreateNonRealtimeInstance(); static MediaStreamGraph* CreateNonRealtimeInstance();
// Idempotent
static void DestroyNonRealtimeInstance(MediaStreamGraph* aGraph); static void DestroyNonRealtimeInstance(MediaStreamGraph* aGraph);
// Control API. // Control API.
@ -1022,6 +1023,8 @@ public:
* in main-thread stream state. * in main-thread stream state.
*/ */
int64_t GetCurrentGraphUpdateIndex() { return mGraphUpdatesSent; } int64_t GetCurrentGraphUpdateIndex() { return mGraphUpdatesSent; }
bool IsNonRealtime() const;
/** /**
* Start processing non-realtime for a specific number of ticks. * Start processing non-realtime for a specific number of ticks.
*/ */

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

@ -79,7 +79,7 @@ public:
return GetOwner(); return GetOwner();
} }
void Shutdown(); void Shutdown(); // idempotent
void Suspend(); void Suspend();
void Resume(); void Resume();

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

@ -235,6 +235,19 @@ AudioDestinationNode::AudioDestinationNode(AudioContext* aContext,
mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM); mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM);
} }
void
AudioDestinationNode::DestroyMediaStream()
{
if (!mStream)
return;
MediaStreamGraph* graph = mStream->Graph();
if (graph->IsNonRealtime()) {
MediaStreamGraph::DestroyNonRealtimeInstance(graph);
}
AudioNode::DestroyMediaStream();
}
uint32_t uint32_t
AudioDestinationNode::MaxChannelCount() const AudioDestinationNode::MaxChannelCount() const
{ {

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

@ -25,6 +25,8 @@ public:
uint32_t aLength = 0, uint32_t aLength = 0,
float aSampleRate = 0.0f); float aSampleRate = 0.0f);
virtual void DestroyMediaStream() MOZ_OVERRIDE;
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
virtual JSObject* WrapObject(JSContext* aCx, virtual JSObject* WrapObject(JSContext* aCx,