Bug 1189506. Give AudioContext non-owning pointers to all its AudioNodes. r=karl

--HG--
extra : commitid : 8qGgR45qFgU
extra : rebase_source : 95285c6403f8578736826a908f1010093e09e59d
This commit is contained in:
Robert O'Callahan 2015-09-03 17:12:25 +12:00
parent ab3e136bf0
commit edc3706647
3 changed files with 23 additions and 13 deletions

View File

@ -98,7 +98,6 @@ AudioContext::AudioContext(nsPIDOMWindow* aWindow,
, mSampleRate(GetSampleRateForAudioContext(aIsOffline, aSampleRate))
, mAudioContextState(AudioContextState::Suspended)
, mNumberOfChannels(aNumberOfChannels)
, mNodeCount(0)
, mIsOffline(aIsOffline)
, mIsStarted(!aIsOffline)
, mIsShutDown(false)
@ -938,17 +937,27 @@ AudioContext::Close(ErrorResult& aRv)
}
void
AudioContext::UpdateNodeCount(int32_t aDelta)
AudioContext::RegisterNode(AudioNode* aNode)
{
bool firstNode = mNodeCount == 0;
mNodeCount += aDelta;
MOZ_ASSERT(mNodeCount >= 0);
MOZ_ASSERT(!mAllNodes.Contains(aNode));
mAllNodes.PutEntry(aNode);
// mDestinationNode may be null when we're destroying nodes unlinked by CC.
// Skipping unnecessary calls after shutdown avoids RunInStableState events
// getting stuck in CycleCollectedJSRuntime during final cycle collection
// (bug 1200514).
if (!firstNode && mDestination && !mIsShutDown) {
mDestination->SetIsOnlyNodeForContext(mNodeCount == 1);
if (mDestination && !mIsShutDown) {
mDestination->SetIsOnlyNodeForContext(mAllNodes.Count() == 1);
}
}
void
AudioContext::UnregisterNode(AudioNode* aNode)
{
MOZ_ASSERT(mAllNodes.Contains(aNode));
mAllNodes.RemoveEntry(aNode);
// mDestinationNode may be null when we're destroying nodes unlinked by CC
if (mDestination) {
mDestination->SetIsOnlyNodeForContext(mAllNodes.Count() == 1);
}
}

View File

@ -303,7 +303,8 @@ public:
AudioChannel TestAudioChannelInAudioNodeStream();
void UpdateNodeCount(int32_t aDelta);
void RegisterNode(AudioNode* aNode);
void UnregisterNode(AudioNode* aNode);
double DOMTimeToStreamTime(double aTime) const
{
@ -361,6 +362,8 @@ private:
// See RegisterActiveNode. These will keep the AudioContext alive while it
// is rendering and the window remains alive.
nsTHashtable<nsRefPtrHashKey<AudioNode> > mActiveNodes;
// Raw (non-owning) references to all AudioNodes for this AudioContext.
nsTHashtable<nsPtrHashKey<AudioNode> > mAllNodes;
// Hashsets containing all the PannerNodes, to compute the doppler shift.
// These are weak pointers.
nsTHashtable<nsPtrHashKey<PannerNode> > mPannerNodes;
@ -368,8 +371,6 @@ private:
nsRefPtr<BasicWaveFormCache> mBasicWaveFormCache;
// Number of channels passed in the OfflineAudioContext ctor.
uint32_t mNumberOfChannels;
// Number of nodes that currently exist for this AudioContext
int32_t mNodeCount;
bool mIsOffline;
bool mIsStarted;
bool mIsShutDown;

View File

@ -23,7 +23,7 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(AudioNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AudioNode, DOMEventTargetHelper)
tmp->DisconnectFromGraph();
if (tmp->mContext) {
tmp->mContext->UpdateNodeCount(-1);
tmp->mContext->UnregisterNode(tmp);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutputNodes)
@ -72,7 +72,7 @@ AudioNode::AudioNode(AudioContext* aContext,
{
MOZ_ASSERT(aContext);
DOMEventTargetHelper::BindToOwner(aContext->GetParentObject());
aContext->UpdateNodeCount(1);
aContext->RegisterNode(this);
}
AudioNode::~AudioNode()
@ -85,7 +85,7 @@ AudioNode::~AudioNode()
"The webaudio-node-demise notification must have been sent");
#endif
if (mContext) {
mContext->UpdateNodeCount(-1);
mContext->UnregisterNode(this);
}
}