Commit 68a3594c authored by haraken@chromium.org's avatar haraken@chromium.org

Oilpan: Don't destruct HRTFDatabaseLoader::m_thread during a sweeping phase

It is not allowed to destruct HRTFDatabaseLoader::m_thread during a sweeping phase
because WebThreadSupportingGC's destructor enters a safe point scope.
This CL avoids the situation by explicitly joining with the loader thread in AudioContext::uninitialize().

In order to make sure that the loader thread finishes touching m_thread,
this CL posts a clean-up task and wait for its completion before calling
m_thread.clear().

BUG=432041

Review URL: https://codereview.chromium.org/711323002

git-svn-id: svn://svn.chromium.org/blink/trunk@185177 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 9bd72416
...@@ -201,6 +201,9 @@ void AudioContext::uninitialize() ...@@ -201,6 +201,9 @@ void AudioContext::uninitialize()
// Get rid of the sources which may still be playing. // Get rid of the sources which may still be playing.
derefUnfinishedSourceNodes(); derefUnfinishedSourceNodes();
ASSERT(m_listener);
m_listener->waitForHRTFDatabaseLoaderThreadCompletion();
clear(); clear();
} }
......
...@@ -92,7 +92,8 @@ bool AudioListener::isHRTFDatabaseLoaded() ...@@ -92,7 +92,8 @@ bool AudioListener::isHRTFDatabaseLoaded()
void AudioListener::waitForHRTFDatabaseLoaderThreadCompletion() void AudioListener::waitForHRTFDatabaseLoaderThreadCompletion()
{ {
m_hrtfDatabaseLoader->waitForLoaderThreadCompletion(); if (m_hrtfDatabaseLoader)
m_hrtfDatabaseLoader->waitForLoaderThreadCompletion();
} }
void AudioListener::markPannersAsDirty(unsigned type) void AudioListener::markPannersAsDirty(unsigned type)
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "platform/audio/HRTFDatabaseLoader.h" #include "platform/audio/HRTFDatabaseLoader.h"
#include "platform/Task.h" #include "platform/Task.h"
#include "platform/TaskSynchronizer.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "wtf/MainThread.h" #include "wtf/MainThread.h"
...@@ -71,10 +72,10 @@ HRTFDatabaseLoader::HRTFDatabaseLoader(float sampleRate) ...@@ -71,10 +72,10 @@ HRTFDatabaseLoader::HRTFDatabaseLoader(float sampleRate)
HRTFDatabaseLoader::~HRTFDatabaseLoader() HRTFDatabaseLoader::~HRTFDatabaseLoader()
{ {
ASSERT(isMainThread()); ASSERT(isMainThread());
waitForLoaderThreadCompletion(); ASSERT(!m_thread);
} }
void HRTFDatabaseLoader::load() void HRTFDatabaseLoader::loadTask()
{ {
ASSERT(!isMainThread()); ASSERT(!isMainThread());
m_thread->attachGC(); m_thread->attachGC();
...@@ -98,7 +99,7 @@ void HRTFDatabaseLoader::loadAsynchronously() ...@@ -98,7 +99,7 @@ void HRTFDatabaseLoader::loadAsynchronously()
if (!m_hrtfDatabase && !m_thread) { if (!m_hrtfDatabase && !m_thread) {
// Start the asynchronous database loading process. // Start the asynchronous database loading process.
m_thread = WebThreadSupportingGC::create("HRTF database loader"); m_thread = WebThreadSupportingGC::create("HRTF database loader");
m_thread->postTask(new Task(WTF::bind(&HRTFDatabaseLoader::load, this))); m_thread->postTask(new Task(WTF::bind(&HRTFDatabaseLoader::loadTask, this)));
} }
} }
...@@ -108,8 +109,21 @@ bool HRTFDatabaseLoader::isLoaded() ...@@ -108,8 +109,21 @@ bool HRTFDatabaseLoader::isLoaded()
return m_hrtfDatabase; return m_hrtfDatabase;
} }
// This cleanup task is needed just to make sure that the loader thread finishes
// the load task and thus the loader thread doesn't touch m_thread any more.
void HRTFDatabaseLoader::cleanupTask(TaskSynchronizer* sync)
{
sync->taskCompleted();
}
void HRTFDatabaseLoader::waitForLoaderThreadCompletion() void HRTFDatabaseLoader::waitForLoaderThreadCompletion()
{ {
if (!m_thread)
return;
TaskSynchronizer sync;
m_thread->postTask(new Task(WTF::bind(&HRTFDatabaseLoader::cleanupTask, this, &sync)));
sync.waitForTaskCompletion();
m_thread.clear(); m_thread.clear();
} }
......
...@@ -37,6 +37,8 @@ ...@@ -37,6 +37,8 @@
namespace blink { namespace blink {
class TaskSynchronizer;
// HRTFDatabaseLoader will asynchronously load the default HRTFDatabase in a new thread. // HRTFDatabaseLoader will asynchronously load the default HRTFDatabase in a new thread.
class PLATFORM_EXPORT HRTFDatabaseLoader final : public GarbageCollectedFinalized<HRTFDatabaseLoader> { class PLATFORM_EXPORT HRTFDatabaseLoader final : public GarbageCollectedFinalized<HRTFDatabaseLoader> {
...@@ -60,9 +62,6 @@ public: ...@@ -60,9 +62,6 @@ public:
float databaseSampleRate() const { return m_databaseSampleRate; } float databaseSampleRate() const { return m_databaseSampleRate; }
// Called in asynchronous loading thread.
void load();
void trace(Visitor*) { } void trace(Visitor*) { }
private: private:
...@@ -73,6 +72,10 @@ private: ...@@ -73,6 +72,10 @@ private:
// This must be called from the main thread. // This must be called from the main thread.
void loadAsynchronously(); void loadAsynchronously();
// Called in asynchronous loading thread.
void loadTask();
void cleanupTask(TaskSynchronizer*);
// Holding a m_lock is required when accessing m_hrtfDatabase since we access it from multiple threads. // Holding a m_lock is required when accessing m_hrtfDatabase since we access it from multiple threads.
Mutex m_lock; Mutex m_lock;
OwnPtr<HRTFDatabase> m_hrtfDatabase; OwnPtr<HRTFDatabase> m_hrtfDatabase;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment