Bug 829309 - Assertion re-entering a hashtable in nsAudioChannelService, r=mrbkap

This commit is contained in:
Andrea Marchesini 2013-01-10 23:56:20 +01:00
parent 6cbbf2b5b2
commit 0259327257
3 changed files with 37 additions and 31 deletions

View File

@ -87,9 +87,9 @@ void
AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
AudioChannelType aType)
{
AudioChannelAgentData data = { aType,
true /* mElementHidden */,
true /* mMuted */ };
AudioChannelAgentData* data = new AudioChannelAgentData(aType,
true /* mElementHidden */,
true /* mMuted */);
mAgents.Put(aAgent, data);
RegisterType(aType, CONTENT_PARENT_UNKNOWN_CHILD_ID);
}
@ -111,13 +111,12 @@ AudioChannelService::RegisterType(AudioChannelType aType, uint64_t aChildID)
void
AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
{
AudioChannelAgentData data;
if (!mAgents.Get(aAgent, &data)) {
return;
}
nsAutoPtr<AudioChannelAgentData> data;
mAgents.RemoveAndForget(aAgent, data);
mAgents.Remove(aAgent);
UnregisterType(data.mType, data.mElementHidden, CONTENT_PARENT_UNKNOWN_CHILD_ID);
if (data) {
UnregisterType(data->mType, data->mElementHidden, CONTENT_PARENT_UNKNOWN_CHILD_ID);
}
}
void
@ -141,20 +140,17 @@ AudioChannelService::UnregisterType(AudioChannelType aType,
bool
AudioChannelService::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden)
{
AudioChannelAgentData data;
AudioChannelAgentData* data;
if (!mAgents.Get(aAgent, &data)) {
return true;
}
bool muted = GetMutedInternal(data.mType, CONTENT_PARENT_UNKNOWN_CHILD_ID,
aElementHidden, data.mElementHidden);
bool muted = GetMutedInternal(data->mType, CONTENT_PARENT_UNKNOWN_CHILD_ID,
aElementHidden, data->mElementHidden);
// Update visibility.
if (data.mElementHidden != aElementHidden || data.mMuted != muted) {
data.mElementHidden = aElementHidden;
data.mMuted = muted;
mAgents.Put(aAgent, data);
}
data->mElementHidden = aElementHidden;
data->mMuted = muted;
SendAudioChannelChangedNotification();
return muted;
@ -277,7 +273,7 @@ AudioChannelService::SendAudioChannelChangedNotification()
PLDHashOperator
AudioChannelService::NotifyEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData aData, void* aUnused)
AudioChannelAgentData* aData, void* aUnused)
{
MOZ_ASSERT(aAgent);
aAgent->NotifyAudioChannelStateChanged();

View File

@ -12,7 +12,7 @@
#include "AudioChannelCommon.h"
#include "AudioChannelAgent.h"
#include "nsDataHashtable.h"
#include "nsClassHashtable.h"
namespace mozilla {
namespace dom {
@ -100,7 +100,16 @@ protected:
AudioChannelInternalType GetInternalType(AudioChannelType aType,
bool aElementHidden);
struct AudioChannelAgentData {
class AudioChannelAgentData {
public:
AudioChannelAgentData(AudioChannelType aType,
bool aElementHidden,
bool aMuted)
: mType(aType)
, mElementHidden(aElementHidden)
, mMuted(aMuted)
{}
AudioChannelType mType;
bool mElementHidden;
bool mMuted;
@ -108,9 +117,9 @@ protected:
static PLDHashOperator
NotifyEnumerator(AudioChannelAgent* aAgent,
AudioChannelAgentData aData, void *aUnused);
AudioChannelAgentData* aData, void *aUnused);
nsDataHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents;
nsClassHashtable< nsPtrHashKey<AudioChannelAgent>, AudioChannelAgentData > mAgents;
nsTArray<uint64_t> mChannelCounters[AUDIO_CHANNEL_INT_LAST];

View File

@ -59,7 +59,7 @@ AudioChannelServiceChild::~AudioChannelServiceChild()
bool
AudioChannelServiceChild::GetMuted(AudioChannelAgent* aAgent, bool aElementHidden)
{
AudioChannelAgentData data;
AudioChannelAgentData* data;
if (!mAgents.Get(aAgent, &data)) {
return true;
}
@ -68,15 +68,12 @@ AudioChannelServiceChild::GetMuted(AudioChannelAgent* aAgent, bool aElementHidde
bool muted = true;
if (cc) {
cc->SendAudioChannelGetMuted(data.mType, aElementHidden, data.mElementHidden, &muted);
cc->SendAudioChannelGetMuted(data->mType, aElementHidden, data->mElementHidden, &muted);
}
// Update visibility.
if (data.mElementHidden != aElementHidden || data.mMuted != muted) {
data.mElementHidden = aElementHidden;
data.mMuted = muted;
mAgents.Put(aAgent, data);
}
data->mElementHidden = aElementHidden;
data->mMuted = muted;
if (cc) {
cc->SendAudioChannelChangedNotification();
@ -105,11 +102,15 @@ AudioChannelServiceChild::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
void
AudioChannelServiceChild::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
{
AudioChannelAgentData data;
if (!mAgents.Get(aAgent, &data)) {
AudioChannelAgentData *pData;
if (!mAgents.Get(aAgent, &pData)) {
return;
}
// We need to keep a copy because unregister will remove the
// AudioChannelAgentData object from the hashtable.
AudioChannelAgentData data(*pData);
AudioChannelService::UnregisterAudioChannelAgent(aAgent);
ContentChild *cc = ContentChild::GetSingleton();