Move some code related to database closing from the destructor to
authordumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 19 Dec 2009 01:27:14 +0000 (01:27 +0000)
committerdumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 19 Dec 2009 01:27:14 +0000 (01:27 +0000)
the close() method. This would allow us to do things such as post
tasks to other threads when a database closes, which cannot be
done now, because we cannot increment the ref count to a database
object when we're in its destructor.

Reviewed by Dmitry Titov.

https://bugs.webkit.org/show_bug.cgi?id=32626

* storage/Database.cpp:
(WebCore::Database::~Database):
(WebCore::Database::close):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@52367 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/storage/Database.cpp

index a0da1dfbadf3f00f7c3ed2a99a08bdc6a72aa470..0694e8234107d01498515664e35d5e2990b43e6d 100644 (file)
@@ -1,3 +1,19 @@
+2009-12-16  Dumitru Daniliuc  <dumi@chromium.org>
+
+        Reviewed by Dmitry Titov.
+
+        Move some code related to database closing from the destructor to
+        the close() method. This would allow us to do things such as post
+        tasks to other threads when a database closes, which cannot be
+        done now, because we cannot increment the ref count to a database
+        object when we're in its destructor.
+
+        https://bugs.webkit.org/show_bug.cgi?id=32626
+
+        * storage/Database.cpp:
+        (WebCore::Database::~Database):
+        (WebCore::Database::close):
+
 2009-12-18  Jon Honeycutt  <jhoneycutt@apple.com>
 
         REGRESSION(r52233): MSAA: Accessibility role of lists is wrong
index 29dec2642ffd91de584de8182eb1849ed7ec2902..72414b49dade70c78c376548bdf36f45fb852563 100644 (file)
@@ -198,12 +198,6 @@ static void derefDocument(void* document)
 
 Database::~Database()
 {
-    if (m_document->databaseThread())
-        m_document->databaseThread()->unscheduleDatabaseTasks(this);
-
-    DatabaseTracker::tracker().removeOpenDatabase(this);
-    m_document->removeOpenDatabase(this);
-
     // Deref m_document on the main thread.
     callOnMainThread(derefDocument, m_document.release().releaseRef());
 }
@@ -333,29 +327,44 @@ void Database::markAsDeletedAndClose()
     synchronizer.waitForTaskCompletion();
 }
 
+static void documentRemoveOpenDatabase(void* context)
+{
+    ASSERT(isMainThread());
+    Database* database = static_cast<Database*>(context);
+    database->document()->removeOpenDatabase(database);
+    database->deref();
+}
+
 void Database::close()
 {
-    if (m_opened) {
-        ASSERT(m_document->databaseThread());
-        ASSERT(currentThread() == document()->databaseThread()->getThreadID());
-        m_sqliteDatabase.close();
-        m_document->databaseThread()->recordDatabaseClosed(this);
-        m_opened = false;
-
-        {
-            MutexLocker locker(guidMutex());
-
-            HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
-            ASSERT(hashSet);
-            ASSERT(hashSet->contains(this));
-            hashSet->remove(this);
-            if (hashSet->isEmpty()) {
-                guidToDatabaseMap().remove(m_guid);
-                delete hashSet;
-                guidToVersionMap().remove(m_guid);
-            }
+    if (!m_opened)
+        return;
+
+    ASSERT(m_document->databaseThread());
+    ASSERT(currentThread() == document()->databaseThread()->getThreadID());
+    m_sqliteDatabase.close();
+    m_document->databaseThread()->recordDatabaseClosed(this);
+    m_opened = false;
+
+    {
+        MutexLocker locker(guidMutex());
+
+        HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
+        ASSERT(hashSet);
+        ASSERT(hashSet->contains(this));
+        hashSet->remove(this);
+        if (hashSet->isEmpty()) {
+            guidToDatabaseMap().remove(m_guid);
+            delete hashSet;
+            guidToVersionMap().remove(m_guid);
         }
     }
+
+    m_document->databaseThread()->unscheduleDatabaseTasks(this);
+
+    DatabaseTracker::tracker().removeOpenDatabase(this);
+    ref();  // deref() called in documentRemoveOpenDatabase()
+    callOnMainThread(documentRemoveOpenDatabase, this);
 }
 
 void Database::stop()