b=865241 don't join HRTFDatabaseLoader thread until it has finished r=ehsan

Also turn some always-true conditions into assertions.

--HG--
extra : rebase_source : a38b75a1a27f25cef7b9dd86a1cca15ce9f67893
This commit is contained in:
Karl Tomlinson 2013-08-09 10:07:42 +12:00
parent 1a98f66b41
commit 705047473b
5 changed files with 61 additions and 16 deletions

View File

@ -6,6 +6,7 @@
#include "WebAudioUtils.h"
#include "AudioNodeStream.h"
#include "blink/HRTFDatabaseLoader.h"
namespace mozilla {
@ -61,5 +62,11 @@ WebAudioUtils::ConvertAudioParamToTicks(AudioParamTimeline& aParam,
aParam.ConvertEventTimesToTicks(ConvertTimeToTickHelper::Convert, &ctth, aDest->SampleRate());
}
void
WebAudioUtils::Shutdown()
{
WebCore::HRTFDatabaseLoader::shutdown();
}
}
}

View File

@ -210,6 +210,8 @@ struct WebAudioUtils {
// Otherwise, this conversion must be well defined.
return IntType(f);
}
static void Shutdown();
};
}

View File

@ -80,11 +80,13 @@ HRTFDatabaseLoader::~HRTFDatabaseLoader()
waitForLoaderThreadCompletion();
m_hrtfDatabase.reset();
// Remove ourself from the map.
s_loaderMap->RemoveEntry(m_databaseSampleRate);
if (s_loaderMap->Count() == 0) {
delete s_loaderMap;
s_loaderMap = nullptr;
if (s_loaderMap) {
// Remove ourself from the map.
s_loaderMap->RemoveEntry(m_databaseSampleRate);
if (s_loaderMap->Count() == 0) {
delete s_loaderMap;
s_loaderMap = nullptr;
}
}
}
@ -142,25 +144,31 @@ static void databaseLoaderEntry(void* threadData)
void HRTFDatabaseLoader::load()
{
MOZ_ASSERT(!NS_IsMainThread());
if (!m_hrtfDatabase.get()) {
// Load the default HRTF database.
m_hrtfDatabase = HRTFDatabase::create(m_databaseSampleRate);
}
MOZ_ASSERT(!m_hrtfDatabase.get(), "Called twice");
// Load the default HRTF database.
m_hrtfDatabase = HRTFDatabase::create(m_databaseSampleRate);
// Notifies the main thread of completion. See loadAsynchronously().
Release();
}
void HRTFDatabaseLoader::loadAsynchronously()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(m_refCnt, "Must not be called before a reference is added");
// Add a reference so that the destructor won't run and wait for the
// loader thread, until load() has completed.
AddRef();
MutexAutoLock locker(m_threadLock);
if (!m_hrtfDatabase.get() && !m_databaseLoaderThread) {
// Start the asynchronous database loading process.
m_databaseLoaderThread =
PR_CreateThread(PR_USER_THREAD, databaseLoaderEntry, this,
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_JOINABLE_THREAD, 0);
}
MOZ_ASSERT(!m_hrtfDatabase.get() && !m_databaseLoaderThread,
"Called twice");
// Start the asynchronous database loading process.
m_databaseLoaderThread =
PR_CreateThread(PR_USER_THREAD, databaseLoaderEntry, this,
PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
PR_JOINABLE_THREAD, 0);
}
bool HRTFDatabaseLoader::isLoaded() const
@ -180,4 +188,24 @@ void HRTFDatabaseLoader::waitForLoaderThreadCompletion()
m_databaseLoaderThread = nullptr;
}
PLDHashOperator
HRTFDatabaseLoader::shutdownEnumFunc(LoaderByRateEntry *entry, void* unused)
{
// Ensure the loader thread's reference is removed for leak analysis.
entry->mLoader->waitForLoaderThreadCompletion();
return PLDHashOperator::PL_DHASH_NEXT;
}
void HRTFDatabaseLoader::shutdown()
{
MOZ_ASSERT(NS_IsMainThread());
if (s_loaderMap) {
// Set s_loaderMap to NULL so that the hashtable is not modified on
// reference release during enumeration.
nsTHashtable<LoaderByRateEntry>* loaderMap = s_loaderMap;
s_loaderMap = nullptr;
loaderMap->EnumerateEntries(shutdownEnumFunc, nullptr);
delete loaderMap;
}
}
} // namespace WebCore

View File

@ -85,6 +85,8 @@ public:
HRTFDatabase* database() { return m_hrtfDatabase.get(); }
float databaseSampleRate() const { return m_databaseSampleRate; }
static void shutdown();
// Called in asynchronous loading thread.
void load();
@ -112,6 +114,10 @@ private:
}
HRTFDatabaseLoader* mLoader;
};
static PLDHashOperator shutdownEnumFunc(LoaderByRateEntry *entry,
void* unused);
// Keeps track of loaders on a per-sample-rate basis.
static nsTHashtable<LoaderByRateEntry> *s_loaderMap; // singleton

View File

@ -92,6 +92,7 @@
#endif
#include "AudioStream.h"
#include "WebAudioUtils.h"
#ifdef MOZ_WIDGET_GONK
#include "nsVolumeService.h"
@ -353,6 +354,7 @@ nsLayoutStatics::Shutdown()
#endif
AudioStream::ShutdownLibrary();
WebAudioUtils::Shutdown();
#ifdef MOZ_WMF
WMFDecoder::UnloadDLLs();