Reviewed by Brady Eidson.
authortimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Feb 2008 06:04:19 +0000 (06:04 +0000)
committertimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 13 Feb 2008 06:04:19 +0000 (06:04 +0000)
        <rdar://problem/5652560> Can't delete database if the website that
        uses it has been opened in this session

        Close the Database on the database thread before deleting the file.
        Tested and works on Windows and Mac.

        * platform/sql/SQLiteDatabase.cpp:
        (WebCore::SQLiteDatabase::close): Assert we are on the opening thread.
        * storage/Database.cpp:
        (WebCore::Database::markAsDeletedAndClose): Unschedule any pending
        Database tasks, and start and imediate DatabaseCloseTask.
        (WebCore::Database::close): Close the SQLDatabase.
        * storage/Database.h: Renamed markAsDeleted to markAsDeletedAndClose.
        * storage/DatabaseTask.cpp:
        (WebCore::DatabaseCloseTask::DatabaseCloseTask): New task.
        (WebCore::DatabaseCloseTask::doPerformTask): Call close on the Database.
        (WebCore::DatabaseCloseTask::debugTaskName): Return "DatabaseCloseTask".
        * storage/DatabaseTask.h: Add DatabaseCloseTask.
        * storage/DatabaseTracker.cpp:
        (WebCore::DatabaseTracker::deleteDatabaseFile): Call the renamed
          markAsDeletedAndClose.

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

WebCore/ChangeLog
WebCore/platform/sql/SQLiteDatabase.cpp
WebCore/storage/Database.cpp
WebCore/storage/Database.h
WebCore/storage/DatabaseTask.cpp
WebCore/storage/DatabaseTask.h
WebCore/storage/DatabaseTracker.cpp

index 7171be6..7e888d7 100644 (file)
@@ -1,3 +1,29 @@
+2008-02-12  Timothy Hatcher  <timothy@apple.com>
+
+        Reviewed by Brady Eidson.
+
+        <rdar://problem/5652560> Can't delete database if the website that
+        uses it has been opened in this session
+
+        Close the Database on the database thread before deleting the file.
+        Tested and works on Windows and Mac.
+
+        * platform/sql/SQLiteDatabase.cpp:
+        (WebCore::SQLiteDatabase::close): Assert we are on the opening thread.
+        * storage/Database.cpp:
+        (WebCore::Database::markAsDeletedAndClose): Unschedule any pending
+        Database tasks, and start and imediate DatabaseCloseTask.
+        (WebCore::Database::close): Close the SQLDatabase.
+        * storage/Database.h: Renamed markAsDeleted to markAsDeletedAndClose.
+        * storage/DatabaseTask.cpp:
+        (WebCore::DatabaseCloseTask::DatabaseCloseTask): New task.
+        (WebCore::DatabaseCloseTask::doPerformTask): Call close on the Database.
+        (WebCore::DatabaseCloseTask::debugTaskName): Return "DatabaseCloseTask".
+        * storage/DatabaseTask.h: Add DatabaseCloseTask.
+        * storage/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::deleteDatabaseFile): Call the renamed
+          markAsDeletedAndClose.
+
 2008-02-12  Oliver Hunt  <oliver@apple.com>
 
         Reviewed by NOBODY (Build fix).
index 597ccdb..8e4e991 100644 (file)
@@ -83,6 +83,7 @@ bool SQLiteDatabase::open(const String& filename)
 void SQLiteDatabase::close()
 {
     if (m_db) {
+        ASSERT(currentThread() == m_openingThread);
         sqlite3_close(m_db);
         m_db = 0;
     }
index 11cc467..1706cfe 100644 (file)
@@ -267,12 +267,26 @@ bool Database::versionMatchesExpected() const
     return true;
 }
 
-void Database::markAsDeleted()
+void Database::markAsDeletedAndClose()
 {
     if (m_deleted)
         return;
+
     LOG(StorageAPI, "Marking %s (%p) as deleted", stringIdentifier().ascii().data(), this);
     m_deleted = true;
+
+    document()->databaseThread()->unscheduleDatabaseTasks(this);
+
+    RefPtr<DatabaseCloseTask> task = new DatabaseCloseTask(this);
+
+    task->lockForSynchronousScheduling();
+    m_document->databaseThread()->scheduleImmediateTask(task.get());
+    task->waitForSynchronousCompletion();
+}
+
+void Database::close()
+{
+    m_sqliteDatabase.close();
 }
 
 unsigned long long Database::databaseSize() const
index d88b8ee..d562222 100644 (file)
@@ -90,9 +90,11 @@ public:
     void setExpectedVersion(const String&);
     bool versionMatchesExpected() const;
 
-    void markAsDeleted();
+    void markAsDeletedAndClose();
     bool deleted() const { return m_deleted; }
 
+    void close();
+
     unsigned long long databaseSize() const;
     unsigned long long maximumSize() const;
 
index ede7b47..7957d2a 100644 (file)
@@ -105,6 +105,26 @@ const char* DatabaseOpenTask::debugTaskName() const
 }
 #endif
 
+// *** DatabaseCloseTask ***
+// Closes the database.
+
+DatabaseCloseTask::DatabaseCloseTask(Database* database)
+    : DatabaseTask(database)
+{
+}
+
+void DatabaseCloseTask::doPerformTask()
+{
+    database()->close();
+}
+
+#ifndef NDEBUG
+const char* DatabaseCloseTask::debugTaskName() const
+{
+    return "DatabaseCloseTask";
+}
+#endif
+
 // *** DatabaseTransactionTask ***
 // Starts a transaction that will report its results via a callback.
 
index b84d076..135438a 100644 (file)
@@ -93,6 +93,18 @@ private:
     bool m_success;
 };
 
+class DatabaseCloseTask : public DatabaseTask
+{
+public:
+    DatabaseCloseTask(Database*);
+
+private:
+    virtual void doPerformTask();
+#ifndef NDEBUG
+    virtual const char* debugTaskName() const;
+#endif
+};
+
 class DatabaseTransactionTask : public DatabaseTask
 {
 public:
index 305fc26..bc2e708 100644 (file)
@@ -744,7 +744,7 @@ bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& n
                     // We have some database open with this name. Mark them as deleted.
                     DatabaseSet::const_iterator end = databaseSet->end();
                     for (DatabaseSet::const_iterator it = databaseSet->begin(); it != end; ++it)
-                        (*it)->markAsDeleted();
+                        (*it)->markAsDeletedAndClose();
                 }
             }
         }