Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / webdatabase / DatabaseThread.cpp
index 1c0f4f0..8ebb4c0 100644 (file)
@@ -51,13 +51,7 @@ DatabaseThread::DatabaseThread()
 DatabaseThread::~DatabaseThread()
 {
     ASSERT(m_openDatabaseSet.isEmpty());
-    // Oilpan: The database thread must have finished its cleanup tasks before
-    // the following clear(). Otherwise, WebThread destructor blocks the caller
-    // thread, and causes a deadlock with ThreadState cleanup.
-    // DatabaseContext::stop() asks the database thread to close all of
-    // databases, and wait until GC heap cleanup of the database thread. So we
-    // can safely destruct WebThread here.
-    m_thread.clear();
+    ASSERT(!m_thread);
 }
 
 void DatabaseThread::trace(Visitor* visitor)
@@ -72,36 +66,35 @@ void DatabaseThread::start()
 {
     if (m_thread)
         return;
-    m_thread = adoptPtr(Platform::current()->createThread("WebCore: Database"));
+    m_thread = WebThreadSupportingGC::create("WebCore: Database");
     m_thread->postTask(new Task(WTF::bind(&DatabaseThread::setupDatabaseThread, this)));
 }
 
 void DatabaseThread::setupDatabaseThread()
 {
-    m_pendingGCRunner = adoptPtr(new PendingGCRunner);
-    m_messageLoopInterruptor = adoptPtr(new MessageLoopInterruptor(m_thread.get()));
-    m_thread->addTaskObserver(m_pendingGCRunner.get());
-    ThreadState::attach();
-    ThreadState::current()->addInterruptor(m_messageLoopInterruptor.get());
+    m_thread->attachGC();
 }
 
-void DatabaseThread::requestTermination(TaskSynchronizer *cleanupSync)
+void DatabaseThread::terminate()
 {
-    MutexLocker lock(m_terminationRequestedMutex);
-    ASSERT(!m_terminationRequested);
-    m_terminationRequested = true;
-    m_cleanupSync = cleanupSync;
-    WTF_LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
-    m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread, this)));
+    TaskSynchronizer sync;
+    {
+        MutexLocker lock(m_terminationRequestedMutex);
+        ASSERT(!m_terminationRequested);
+        m_terminationRequested = true;
+        m_cleanupSync = &sync;
+        WTF_LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this);
+        m_thread->postTask(new Task(WTF::bind(&DatabaseThread::cleanupDatabaseThread, this)));
+    }
+    sync.waitForTaskCompletion();
+    // The WebThread destructor blocks until all the tasks of the database
+    // thread are processed. However, it shouldn't block at all because
+    // the database thread has already finished processing the cleanup task.
+    m_thread.clear();
 }
 
-bool DatabaseThread::terminationRequested(TaskSynchronizer* taskSynchronizer) const
+bool DatabaseThread::terminationRequested() const
 {
-#if ENABLE(ASSERT)
-    if (taskSynchronizer)
-        taskSynchronizer->setHasCheckedForTermination();
-#endif
-
     MutexLocker lock(m_terminationRequestedMutex);
     return m_terminationRequested;
 }
@@ -117,10 +110,10 @@ void DatabaseThread::cleanupDatabaseThread()
     // inconsistent or locked state.
     if (m_openDatabaseSet.size() > 0) {
         // As the call to close will modify the original set, we must take a copy to iterate over.
-        WillBeHeapHashSet<RefPtrWillBeMember<DatabaseBackend> > openSetCopy;
+        WillBeHeapHashSet<RefPtrWillBeMember<Database> > openSetCopy;
         openSetCopy.swap(m_openDatabaseSet);
-        WillBeHeapHashSet<RefPtrWillBeMember<DatabaseBackend> >::iterator end = openSetCopy.end();
-        for (WillBeHeapHashSet<RefPtrWillBeMember<DatabaseBackend> >::iterator it = openSetCopy.begin(); it != end; ++it)
+        WillBeHeapHashSet<RefPtrWillBeMember<Database> >::iterator end = openSetCopy.end();
+        for (WillBeHeapHashSet<RefPtrWillBeMember<Database> >::iterator it = openSetCopy.begin(); it != end; ++it)
             (*it)->close();
     }
 
@@ -129,17 +122,12 @@ void DatabaseThread::cleanupDatabaseThread()
 
 void DatabaseThread::cleanupDatabaseThreadCompleted()
 {
-    ThreadState::current()->removeInterruptor(m_messageLoopInterruptor.get());
-    ThreadState::detach();
-    // We need to unregister PendingGCRunner before finising this task to avoid
-    // PendingGCRunner::didProcessTask accesses dead ThreadState.
-    m_thread->removeTaskObserver(m_pendingGCRunner.get());
-
+    m_thread->detachGC();
     if (m_cleanupSync) // Someone wanted to know when we were done cleaning up.
         m_cleanupSync->taskCompleted();
 }
 
-void DatabaseThread::recordDatabaseOpen(DatabaseBackend* database)
+void DatabaseThread::recordDatabaseOpen(Database* database)
 {
     ASSERT(isDatabaseThread());
     ASSERT(database);
@@ -147,7 +135,7 @@ void DatabaseThread::recordDatabaseOpen(DatabaseBackend* database)
     m_openDatabaseSet.add(database);
 }
 
-void DatabaseThread::recordDatabaseClosed(DatabaseBackend* database)
+void DatabaseThread::recordDatabaseClosed(Database* database)
 {
     ASSERT(isDatabaseThread());
     ASSERT(database);
@@ -155,7 +143,7 @@ void DatabaseThread::recordDatabaseClosed(DatabaseBackend* database)
     m_openDatabaseSet.remove(database);
 }
 
-bool DatabaseThread::isDatabaseOpen(DatabaseBackend* database)
+bool DatabaseThread::isDatabaseOpen(Database* database)
 {
     ASSERT(isDatabaseThread());
     ASSERT(database);
@@ -166,7 +154,7 @@ bool DatabaseThread::isDatabaseOpen(DatabaseBackend* database)
 void DatabaseThread::scheduleTask(PassOwnPtr<DatabaseTask> task)
 {
     ASSERT(m_thread);
-    ASSERT(!task->hasSynchronizer() || task->hasCheckedForTermination());
+    ASSERT(!terminationRequested());
     // WebThread takes ownership of the task.
     m_thread->postTask(task.leakPtr());
 }