Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / parser / HTMLParserThread.cpp
index 75c8e82..aeaca7d 100644 (file)
 #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;
 
@@ -53,28 +54,60 @@ void HTMLParserThread::init()
     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