#include "core/html/parser/HTMLParserThread.h"
#include "platform/Task.h"
+#include "platform/TaskSynchronizer.h"
#include "public/platform/Platform.h"
#include "wtf/PassOwnPtr.h"
-namespace WebCore {
+namespace blink {
static HTMLParserThread* s_sharedThread = 0;
s_sharedThread = new HTMLParserThread;
}
+void HTMLParserThread::setupHTMLParserThread()
+{
+ m_pendingGCRunner = adoptPtr(new PendingGCRunner);
+ m_messageLoopInterruptor = adoptPtr(new MessageLoopInterruptor(&platformThread()));
+ platformThread().addTaskObserver(m_pendingGCRunner.get());
+ ThreadState::attach();
+ ThreadState::current()->addInterruptor(m_messageLoopInterruptor.get());
+}
+
void HTMLParserThread::shutdown()
{
ASSERT(s_sharedThread);
+ // currentThread will always be non-null in production, but can be null in Chromium unit tests.
+ if (blink::Platform::current()->currentThread() && s_sharedThread->isRunning()) {
+ TaskSynchronizer taskSynchronizer;
+ s_sharedThread->postTask(WTF::bind(&HTMLParserThread::cleanupHTMLParserThread, s_sharedThread, &taskSynchronizer));
+ taskSynchronizer.waitForTaskCompletion();
+ }
delete s_sharedThread;
s_sharedThread = 0;
}
+void HTMLParserThread::cleanupHTMLParserThread(TaskSynchronizer* taskSynchronizer)
+{
+ ThreadState::current()->removeInterruptor(m_messageLoopInterruptor.get());
+ ThreadState::detach();
+ platformThread().removeTaskObserver(m_pendingGCRunner.get());
+ m_pendingGCRunner = nullptr;
+ m_messageLoopInterruptor = nullptr;
+ taskSynchronizer->taskCompleted();
+}
+
HTMLParserThread* HTMLParserThread::shared()
{
return s_sharedThread;
}
-blink::WebThread& HTMLParserThread::ensureThread()
+blink::WebThread& HTMLParserThread::platformThread()
{
- if (!m_thread)
+ if (!isRunning()) {
m_thread = adoptPtr(blink::Platform::current()->createThread("HTMLParserThread"));
+ postTask(WTF::bind(&HTMLParserThread::setupHTMLParserThread, this));
+ }
return *m_thread;
}
+bool HTMLParserThread::isRunning()
+{
+ return !!m_thread;
+}
+
void HTMLParserThread::postTask(const Closure& closure)
{
- ensureThread().postTask(new Task(closure));
+ platformThread().postTask(new Task(closure));
}
-} // namespace WebCore
+} // namespace blink