WebCore: Adding a way to get the set of all open database handles pointing
authordumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Feb 2010 21:20:01 +0000 (21:20 +0000)
committerdumi@chromium.org <dumi@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 8 Feb 2010 21:20:01 +0000 (21:20 +0000)
to a given database.
https://bugs.webkit.org/show_bug.cgi?id=34619

Reviewed by Jeremy Orlow.

Sometimes we need to be able to close all handles to a database as
soon as possible (to delete the DB file, for example).

* storage/DatabaseTracker.cpp:
(WebCore::DatabaseTracker::getOpenDatabases):
* storage/DatabaseTracker.h:
* storage/chromium/DatabaseTrackerChromium.cpp:
(WebCore::DatabaseTracker::addOpenDatabase):
(WebCore::DatabaseTracker::removeOpenDatabase):
(WebCore::DatabaseTracker::getOpenDatabases):

WebKit/chromium: Adding a way to close all database handles pointing to a certain
database as soon as possible.
https://bugs.webkit.org/show_bug.cgi?id=34619

Reviewed by Jeremy Orlow.

* public/WebDatabase.h:
* src/WebDatabase.cpp:
(WebKit::WebDatabase::closeDatabaseImmediately):

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

WebCore/ChangeLog
WebCore/storage/DatabaseTracker.cpp
WebCore/storage/DatabaseTracker.h
WebCore/storage/chromium/DatabaseTrackerChromium.cpp
WebKit/chromium/ChangeLog
WebKit/chromium/public/WebDatabase.h
WebKit/chromium/src/WebDatabase.cpp

index b9a57e8acc1913f9f1edebdee2b9ed45aa4322b9..3f8371e07cbcd36e03d1181b097e27f50011b7b8 100644 (file)
@@ -1,3 +1,22 @@
+2010-02-05  Dumitru Daniliuc  <dumi@chromium.org>
+
+        Reviewed by Jeremy Orlow.
+
+        Adding a way to get the set of all open database handles pointing
+        to a given database.
+        https://bugs.webkit.org/show_bug.cgi?id=34619
+
+        Sometimes we need to be able to close all handles to a database as
+        soon as possible (to delete the DB file, for example).
+
+        * storage/DatabaseTracker.cpp:
+        (WebCore::DatabaseTracker::getOpenDatabases):
+        * storage/DatabaseTracker.h:
+        * storage/chromium/DatabaseTrackerChromium.cpp:
+        (WebCore::DatabaseTracker::addOpenDatabase):
+        (WebCore::DatabaseTracker::removeOpenDatabase):
+        (WebCore::DatabaseTracker::getOpenDatabases):
+
 2010-02-08  Dirk Schulze  <krit@webkit.org>
 
         Unreviewed windows build-fix.
index bed83a7e7c70df691c7a4bafa0f999f6ce20d202..76492c9f0cae83513911ab7c820e4f4325cb8ee8 100644 (file)
@@ -478,6 +478,24 @@ void DatabaseTracker::removeOpenDatabase(Database* database)
     delete nameMap;
 }
 
+void DatabaseTracker::getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet<RefPtr<Database> >* databases)
+{
+    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+    if (!m_openDatabaseMap)
+        return;
+
+    DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin);
+    if (!nameMap)
+        return;
+
+    DatabaseSet* databaseSet = nameMap->get(name);
+    if (!databaseSet)
+        return;
+
+    for (DatabaseSet::iterator it = databaseSet->begin(); it != databaseSet->end(); ++it)
+        databases->add(*it);
+}
+
 unsigned long long DatabaseTracker::usageForOrigin(SecurityOrigin* origin)
 {
     ASSERT(currentThread() == m_thread);
index 38a341811049b178ab4bfd44ddd7a7292800b833..4640b1813ee74e5807123ea685ecf1750e8fbef8 100644 (file)
 #if ENABLE(DATABASE)
 
 #include "PlatformString.h"
+#include "StringHash.h"
+#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
 
 #if !PLATFORM(CHROMIUM)
 #include "DatabaseDetails.h"
 #include "SQLiteDatabase.h"
-#include "StringHash.h"
-#include <wtf/HashMap.h>
-#include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
 #endif // !PLATFORM(CHROMIUM)
 
@@ -48,11 +48,12 @@ class Database;
 class ScriptExecutionContext;
 class SecurityOrigin;
 
+struct SecurityOriginHash;
+
 #if !PLATFORM(CHROMIUM)
 class DatabaseTrackerClient;
 class OriginQuotaManager;
 
-struct SecurityOriginHash;
 struct SecurityOriginTraits;
 #endif // !PLATFORM(CHROMIUM)
 
@@ -69,12 +70,20 @@ public:
 
     void addOpenDatabase(Database*);
     void removeOpenDatabase(Database*);
+    void getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet<RefPtr<Database> >* databases);
 
     unsigned long long getMaxSizeForDatabase(const Database*);
 
 private:
     DatabaseTracker();
 
+    typedef HashSet<Database*> DatabaseSet;
+    typedef HashMap<String, DatabaseSet*> DatabaseNameMap;
+    typedef HashMap<RefPtr<SecurityOrigin>, DatabaseNameMap*, SecurityOriginHash> DatabaseOriginMap;
+
+    Mutex m_openDatabaseMapGuard;
+    mutable OwnPtr<DatabaseOriginMap> m_openDatabaseMap;
+
 #if !PLATFORM(CHROMIUM)
 public:
     void setDatabaseDirectoryPath(const String&);
@@ -123,13 +132,6 @@ private:
     Mutex m_quotaMapGuard;
     mutable OwnPtr<QuotaMap> m_quotaMap;
 
-    typedef HashSet<Database*> DatabaseSet;
-    typedef HashMap<String, DatabaseSet*> DatabaseNameMap;
-    typedef HashMap<RefPtr<SecurityOrigin>, DatabaseNameMap*, SecurityOriginHash> DatabaseOriginMap;
-
-    Mutex m_openDatabaseMapGuard;
-    mutable OwnPtr<DatabaseOriginMap> m_openDatabaseMap;
-
     OwnPtr<OriginQuotaManager> m_quotaManager;
 
     String m_databaseDirectoryPath;
index e18706b367399066fc6057de494d637b63e17f7f..ac58e077e5ed4642c0942e86479869c02597acf9 100644 (file)
@@ -38,6 +38,7 @@
 #include "QuotaTracker.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
+#include "SecurityOriginHash.h"
 #include "SQLiteFileSystem.h"
 #include <wtf/HashSet.h>
 #include <wtf/MainThread.h>
@@ -76,6 +77,25 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String
 void DatabaseTracker::addOpenDatabase(Database* database)
 {
     ASSERT(database->scriptExecutionContext()->isContextThread());
+    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+    if (!m_openDatabaseMap)
+        m_openDatabaseMap.set(new DatabaseOriginMap());
+
+    DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());
+    if (!nameMap) {
+        nameMap = new DatabaseNameMap();
+        m_openDatabaseMap->set(database->securityOrigin(), nameMap);
+    }
+
+    String name(database->stringIdentifier());
+    DatabaseSet* databaseSet = nameMap->get(name);
+    if (!databaseSet) {
+        databaseSet = new DatabaseSet();
+        nameMap->set(name, databaseSet);
+    }
+
+    databaseSet->add(database);
+
     DatabaseObserver::databaseOpened(database);
 }
 
@@ -107,9 +127,46 @@ void DatabaseTracker::removeOpenDatabase(Database* database)
         return;
     }
 
+    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+    ASSERT(m_openDatabaseMap);
+    DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());
+    ASSERT(nameMap);
+    String name(database->stringIdentifier());
+    DatabaseSet* databaseSet = nameMap->get(name);
+    ASSERT(databaseSet);
+    databaseSet->remove(database);
+
+    if (databaseSet->isEmpty()) {
+        nameMap->remove(name);
+        delete databaseSet;
+        if (nameMap->isEmpty()) {
+            m_openDatabaseMap->remove(database->securityOrigin());
+            delete nameMap;
+        }
+    }
+
     DatabaseObserver::databaseClosed(database);
 }
 
+
+void DatabaseTracker::getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet<RefPtr<Database> >* databases)
+{
+    MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+    if (!m_openDatabaseMap)
+        return;
+
+    DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin);
+    if (!nameMap)
+        return;
+
+    DatabaseSet* databaseSet = nameMap->get(name);
+    if (!databaseSet)
+        return;
+
+    for (DatabaseSet::iterator it = databaseSet->begin(); it != databaseSet->end(); ++it)
+        databases->add(*it);
+}
+
 unsigned long long DatabaseTracker::getMaxSizeForDatabase(const Database* database)
 {
     ASSERT(currentThread() == database->scriptExecutionContext()->databaseThread()->getThreadID());
index 92c3f41058a0720155156be96fd0e78e433340ab..9f43b8f50c4cbe655b3c89090e105a45c2d99afe 100644 (file)
@@ -1,3 +1,15 @@
+2010-02-05  Dumitru Daniliuc  <dumi@chromium.org>
+
+        Reviewed by Jeremy Orlow.
+
+        Adding a way to close all database handles pointing to a certain
+        database as soon as possible.
+        https://bugs.webkit.org/show_bug.cgi?id=34619
+
+        * public/WebDatabase.h:
+        * src/WebDatabase.cpp:
+        (WebKit::WebDatabase::closeDatabaseImmediately):
+
 2010-02-08  Dirk Schulze  <krit@webkit.org>
 
         Reviewed by Nikolas Zimmermann.
index 179e828830e13858fe6906012315619dcbcec261..108201d3a41d17c09b4647cec50162c3728155e4 100644 (file)
@@ -72,6 +72,8 @@ public:
     WEBKIT_API static void updateDatabaseSize(
         const WebString& originIdentifier, const WebString& databaseName,
         unsigned long long databaseSize, unsigned long long spaceAvailable);
+    WEBKIT_API static void closeDatabaseImmediately(
+        const WebString& originIdentifier, const WebString& databaseName);
 
 #if WEBKIT_IMPLEMENTATION
     WebDatabase(const WTF::PassRefPtr<WebCore::Database>&);
index 2cd36b6a173cff94b857e5a54bceb387ebeb42f1..50b9220b787be1c152f300767ba5fa9e8ad36c85 100644 (file)
@@ -32,7 +32,9 @@
 #include "WebDatabase.h"
 
 #include "Database.h"
+#include "DatabaseTask.h"
 #include "DatabaseThread.h"
+#include "DatabaseTracker.h"
 #include "Document.h"
 #include "KURL.h"
 #include "QuotaTracker.h"
@@ -106,6 +108,22 @@ void WebDatabase::updateDatabaseSize(
         originIdentifier, databaseName, databaseSize, spaceAvailable);
 }
 
+void WebDatabase::closeDatabaseImmediately(const WebString& originIdentifier, const WebString& databaseName)
+{
+    HashSet<RefPtr<Database> > databaseHandles;
+    PassRefPtr<SecurityOrigin> originPrp(*WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier));
+    RefPtr<SecurityOrigin> origin = originPrp;
+    DatabaseTracker::tracker().getOpenDatabases(origin.get(), databaseName, &databaseHandles);
+    for (HashSet<RefPtr<Database> >::iterator it = databaseHandles.begin(); it != databaseHandles.end(); ++it) {
+        Database* database = it->get();
+        DatabaseThread* databaseThread = database->scriptExecutionContext()->databaseThread();
+        if (databaseThread && !databaseThread->terminationRequested()) {
+            database->stop();
+            databaseThread->scheduleTask(DatabaseCloseTask::create(database, 0));
+        }
+    }
+}
+
 WebDatabase::WebDatabase(const WTF::PassRefPtr<Database>& database)
     : m_private(static_cast<WebDatabasePrivate*>(database.releaseRef()))
 {