summaryrefslogtreecommitdiff
path: root/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp')
-rw-r--r--Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp368
1 files changed, 185 insertions, 183 deletions
diff --git a/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp b/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
index 1fe9f1aec..8d3fa13a0 100644
--- a/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
+++ b/Source/WebCore/Modules/webdatabase/DatabaseTracker.cpp
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -29,10 +29,13 @@
#include "config.h"
#include "DatabaseTracker.h"
+#if ENABLE(SQL_DATABASE)
+
#include "Chrome.h"
#include "ChromeClient.h"
#include "Database.h"
-#include "DatabaseContext.h"
+#include "DatabaseBackendBase.h"
+#include "DatabaseBackendContext.h"
#include "DatabaseManager.h"
#include "DatabaseManagerClient.h"
#include "DatabaseThread.h"
@@ -44,12 +47,9 @@
#include "SecurityOriginHash.h"
#include "SQLiteFileSystem.h"
#include "SQLiteStatement.h"
-#include "UUID.h"
#include <wtf/MainThread.h>
-#include <wtf/NeverDestroyed.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
-#include <wtf/text/StringBuilder.h>
#if PLATFORM(IOS)
#include "WebCoreThread.h"
@@ -57,12 +57,7 @@
namespace WebCore {
-std::unique_ptr<DatabaseTracker> DatabaseTracker::trackerWithDatabasePath(const String& databasePath)
-{
- return std::unique_ptr<DatabaseTracker>(new DatabaseTracker(databasePath));
-}
-
-static DatabaseTracker* staticTracker = nullptr;
+static DatabaseTracker* staticTracker = 0;
void DatabaseTracker::initializeTracker(const String& databasePath)
{
@@ -82,14 +77,14 @@ DatabaseTracker& DatabaseTracker::tracker()
}
DatabaseTracker::DatabaseTracker(const String& databasePath)
- : m_client(nullptr)
+ : m_client(0)
{
setDatabaseDirectoryPath(databasePath);
}
void DatabaseTracker::setDatabaseDirectoryPath(const String& path)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
ASSERT(!m_database.isOpen());
m_databaseDirectoryPath = path.isolatedCopy();
}
@@ -162,11 +157,11 @@ bool DatabaseTracker::hasAdequateQuotaForOrigin(SecurityOrigin* origin, unsigned
return false;
}
-bool DatabaseTracker::canEstablishDatabase(DatabaseContext* context, const String& name, unsigned long estimatedSize, DatabaseError& error)
+bool DatabaseTracker::canEstablishDatabase(DatabaseBackendContext* context, const String& name, unsigned long estimatedSize, DatabaseError& error)
{
error = DatabaseError::None;
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
SecurityOrigin* origin = context->securityOrigin();
if (isDeletingDatabaseOrOriginFor(origin, name)) {
@@ -214,11 +209,11 @@ bool DatabaseTracker::canEstablishDatabase(DatabaseContext* context, const Strin
// hasAdequateQuotaForOrigin() simple and correct (i.e. bug free), and just
// re-use it. Also note that the path for opening a database involves IO, and
// hence should not be a performance critical path anyway.
-bool DatabaseTracker::retryCanEstablishDatabase(DatabaseContext* context, const String& name, unsigned long estimatedSize, DatabaseError& error)
+bool DatabaseTracker::retryCanEstablishDatabase(DatabaseBackendContext* context, const String& name, unsigned long estimatedSize, DatabaseError& error)
{
error = DatabaseError::None;
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
SecurityOrigin* origin = context->securityOrigin();
// We have already eliminated other types of errors in canEstablishDatabase().
@@ -245,19 +240,19 @@ bool DatabaseTracker::hasEntryForOriginNoLock(SecurityOrigin* origin)
return false;
SQLiteStatement statement(m_database, "SELECT origin FROM Origins where origin=?;");
- if (statement.prepare() != SQLITE_OK) {
+ if (statement.prepare() != SQLResultOk) {
LOG_ERROR("Failed to prepare statement.");
return false;
}
statement.bindText(1, origin->databaseIdentifier());
- return statement.step() == SQLITE_ROW;
+ return statement.step() == SQLResultRow;
}
bool DatabaseTracker::hasEntryForOrigin(SecurityOrigin* origin)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
return hasEntryForOriginNoLock(origin);
}
@@ -273,20 +268,20 @@ bool DatabaseTracker::hasEntryForDatabase(SecurityOrigin* origin, const String&
// We've got a tracker database. Set up a query to ask for the db of interest:
SQLiteStatement statement(m_database, "SELECT guid FROM Databases WHERE origin=? AND name=?;");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
return false;
statement.bindText(1, origin->databaseIdentifier());
statement.bindText(2, databaseIdentifier);
- return statement.step() == SQLITE_ROW;
+ return statement.step() == SQLResultRow;
}
-unsigned long long DatabaseTracker::getMaxSizeForDatabase(const Database* database)
+unsigned long long DatabaseTracker::getMaxSizeForDatabase(const DatabaseBackendBase* database)
{
// The maximum size for a database is the full quota for its origin, minus the current usage within the origin,
// plus the current usage of the given database
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
SecurityOrigin* origin = database->securityOrigin();
unsigned long long quota = quotaForOriginNoLock(origin);
@@ -307,22 +302,33 @@ unsigned long long DatabaseTracker::getMaxSizeForDatabase(const Database* databa
return maxSize;
}
-void DatabaseTracker::closeAllDatabases()
+void DatabaseTracker::interruptAllDatabasesForContext(const DatabaseBackendContext* context)
{
- Vector<Ref<Database>> openDatabases;
+ Vector<RefPtr<DatabaseBackendBase>> openDatabases;
{
- LockHolder openDatabaseMapLock(m_openDatabaseMapGuard);
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+
if (!m_openDatabaseMap)
return;
- for (auto& nameMap : m_openDatabaseMap->values()) {
- for (auto& set : nameMap->values()) {
- for (auto& database : *set)
- openDatabases.append(*database);
+
+ DatabaseNameMap* nameMap = m_openDatabaseMap->get(context->securityOrigin());
+ if (!nameMap)
+ return;
+
+ DatabaseNameMap::const_iterator dbNameMapEndIt = nameMap->end();
+ for (DatabaseNameMap::const_iterator dbNameMapIt = nameMap->begin(); dbNameMapIt != dbNameMapEndIt; ++dbNameMapIt) {
+ DatabaseSet* databaseSet = dbNameMapIt->value;
+ DatabaseSet::const_iterator dbSetEndIt = databaseSet->end();
+ for (DatabaseSet::const_iterator dbSetIt = databaseSet->begin(); dbSetIt != dbSetEndIt; ++dbSetIt) {
+ if ((*dbSetIt)->databaseContext() == context)
+ openDatabases.append(*dbSetIt);
}
}
}
- for (auto& database : openDatabases)
- database->close();
+
+ Vector<RefPtr<DatabaseBackendBase>>::const_iterator openDatabasesEndIt = openDatabases.end();
+ for (Vector<RefPtr<DatabaseBackendBase>>::const_iterator openDatabasesIt = openDatabases.begin(); openDatabasesIt != openDatabasesEndIt; ++openDatabasesIt)
+ (*openDatabasesIt)->interrupt();
}
String DatabaseTracker::originPath(SecurityOrigin* origin) const
@@ -330,16 +336,6 @@ String DatabaseTracker::originPath(SecurityOrigin* origin) const
return SQLiteFileSystem::appendDatabaseFileNameToPath(m_databaseDirectoryPath.isolatedCopy(), origin->databaseIdentifier());
}
-static String generateDatabaseFileName()
-{
- StringBuilder stringBuilder;
-
- stringBuilder.append(createCanonicalUUIDString());
- stringBuilder.appendLiteral(".db");
-
- return stringBuilder.toString();
-}
-
String DatabaseTracker::fullPathForDatabaseNoLock(SecurityOrigin* origin, const String& name, bool createIfNotExists)
{
ASSERT(!m_databaseGuard.tryLock());
@@ -356,7 +352,7 @@ String DatabaseTracker::fullPathForDatabaseNoLock(SecurityOrigin* origin, const
return String();
SQLiteStatement statement(m_database, "SELECT path FROM Databases WHERE origin=? AND name=?;");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
return String();
statement.bindText(1, originIdentifier);
@@ -364,19 +360,18 @@ String DatabaseTracker::fullPathForDatabaseNoLock(SecurityOrigin* origin, const
int result = statement.step();
- if (result == SQLITE_ROW)
+ if (result == SQLResultRow)
return SQLiteFileSystem::appendDatabaseFileNameToPath(originPath, statement.getColumnText(0));
if (!createIfNotExists)
return String();
- if (result != SQLITE_DONE) {
+ if (result != SQLResultDone) {
LOG_ERROR("Failed to retrieve filename from Database Tracker for origin %s, name %s", originIdentifier.ascii().data(), name.ascii().data());
return String();
}
statement.finalize();
- String fileName = generateDatabaseFileName();
-
+ String fileName = SQLiteFileSystem::getFileNameForNewDatabase(originPath, name, originIdentifier, &m_database);
if (!addDatabase(origin, name, fileName))
return String();
@@ -389,32 +384,32 @@ String DatabaseTracker::fullPathForDatabaseNoLock(SecurityOrigin* origin, const
String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String& name, bool createIfNotExists)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
return fullPathForDatabaseNoLock(origin, name, createIfNotExists).isolatedCopy();
}
void DatabaseTracker::origins(Vector<RefPtr<SecurityOrigin>>& originsResult)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
openTrackerDatabase(DontCreateIfDoesNotExist);
if (!m_database.isOpen())
return;
SQLiteStatement statement(m_database, "SELECT origin FROM Origins");
- if (statement.prepare() != SQLITE_OK) {
+ if (statement.prepare() != SQLResultOk) {
LOG_ERROR("Failed to prepare statement.");
return;
}
int result;
- while ((result = statement.step()) == SQLITE_ROW) {
+ while ((result = statement.step()) == SQLResultRow) {
RefPtr<SecurityOrigin> origin = SecurityOrigin::createFromDatabaseIdentifier(statement.getColumnText(0));
originsResult.append(origin->isolatedCopy());
}
originsResult.shrinkToFit();
- if (result != SQLITE_DONE)
+ if (result != SQLResultDone)
LOG_ERROR("Failed to read in all origins from the database.");
}
@@ -427,16 +422,16 @@ bool DatabaseTracker::databaseNamesForOriginNoLock(SecurityOrigin* origin, Vecto
SQLiteStatement statement(m_database, "SELECT name FROM Databases where origin=?;");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
return false;
statement.bindText(1, origin->databaseIdentifier());
int result;
- while ((result = statement.step()) == SQLITE_ROW)
+ while ((result = statement.step()) == SQLResultRow)
resultVector.append(statement.getColumnText(0));
- if (result != SQLITE_DONE) {
+ if (result != SQLResultDone) {
LOG_ERROR("Failed to retrieve all database names for origin %s", origin->databaseIdentifier().ascii().data());
return false;
}
@@ -448,13 +443,13 @@ bool DatabaseTracker::databaseNamesForOrigin(SecurityOrigin* origin, Vector<Stri
{
Vector<String> temp;
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
if (!databaseNamesForOriginNoLock(origin, temp))
return false;
}
- for (auto& databaseName : temp)
- resultVector.append(databaseName.isolatedCopy());
+ for (Vector<String>::iterator iter = temp.begin(); iter != temp.end(); ++iter)
+ resultVector.append(iter->isolatedCopy());
return true;
}
@@ -465,23 +460,23 @@ DatabaseDetails DatabaseTracker::detailsForNameAndOrigin(const String& name, Sec
int64_t expectedUsage;
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
openTrackerDatabase(DontCreateIfDoesNotExist);
if (!m_database.isOpen())
return DatabaseDetails();
SQLiteStatement statement(m_database, "SELECT displayName, estimatedSize FROM Databases WHERE origin=? AND name=?");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
return DatabaseDetails();
statement.bindText(1, originIdentifier);
statement.bindText(2, name);
int result = statement.step();
- if (result == SQLITE_DONE)
+ if (result == SQLResultDone)
return DatabaseDetails();
- if (result != SQLITE_ROW) {
+ if (result != SQLResultRow) {
LOG_ERROR("Error retrieving details for database %s in origin %s from tracker database", name.ascii().data(), originIdentifier.ascii().data());
return DatabaseDetails();
}
@@ -500,25 +495,25 @@ void DatabaseTracker::setDatabaseDetails(SecurityOrigin* origin, const String& n
String originIdentifier = origin->databaseIdentifier();
int64_t guid = 0;
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
openTrackerDatabase(CreateIfDoesNotExist);
if (!m_database.isOpen())
return;
SQLiteStatement statement(m_database, "SELECT guid FROM Databases WHERE origin=? AND name=?");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
return;
statement.bindText(1, originIdentifier);
statement.bindText(2, name);
int result = statement.step();
- if (result == SQLITE_ROW)
+ if (result == SQLResultRow)
guid = statement.getColumnInt64(0);
statement.finalize();
if (guid == 0) {
- if (result != SQLITE_DONE)
+ if (result != SQLResultDone)
LOG_ERROR("Error to determing existence of database %s in origin %s in tracker database", name.ascii().data(), originIdentifier.ascii().data());
else {
// This case should never occur - we should never be setting database details for a database that doesn't already exist in the tracker
@@ -531,14 +526,14 @@ void DatabaseTracker::setDatabaseDetails(SecurityOrigin* origin, const String& n
}
SQLiteStatement updateStatement(m_database, "UPDATE Databases SET displayName=?, estimatedSize=? WHERE guid=?");
- if (updateStatement.prepare() != SQLITE_OK)
+ if (updateStatement.prepare() != SQLResultOk)
return;
updateStatement.bindText(1, displayName);
updateStatement.bindInt64(2, estimatedSize);
updateStatement.bindInt64(3, guid);
- if (updateStatement.step() != SQLITE_DONE) {
+ if (updateStatement.step() != SQLResultDone) {
LOG_ERROR("Failed to update details for database %s in origin %s", name.ascii().data(), originIdentifier.ascii().data());
return;
}
@@ -547,22 +542,22 @@ void DatabaseTracker::setDatabaseDetails(SecurityOrigin* origin, const String& n
m_client->dispatchDidModifyDatabase(origin, name);
}
-void DatabaseTracker::doneCreatingDatabase(Database* database)
+void DatabaseTracker::doneCreatingDatabase(DatabaseBackendBase* database)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
doneCreatingDatabase(database->securityOrigin(), database->stringIdentifier());
}
-void DatabaseTracker::addOpenDatabase(Database* database)
+void DatabaseTracker::addOpenDatabase(DatabaseBackendBase* database)
{
if (!database)
return;
{
- LockHolder openDatabaseMapLock(m_openDatabaseMapGuard);
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
if (!m_openDatabaseMap)
- m_openDatabaseMap = std::make_unique<DatabaseOriginMap>();
+ m_openDatabaseMap = adoptPtr(new DatabaseOriginMap);
String name(database->stringIdentifier());
DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());
@@ -583,13 +578,13 @@ void DatabaseTracker::addOpenDatabase(Database* database)
}
}
-void DatabaseTracker::removeOpenDatabase(Database* database)
+void DatabaseTracker::removeOpenDatabase(DatabaseBackendBase* database)
{
if (!database)
return;
{
- LockHolder openDatabaseMapLock(m_openDatabaseMapGuard);
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
if (!m_openDatabaseMap) {
ASSERT_NOT_REACHED();
@@ -627,9 +622,9 @@ void DatabaseTracker::removeOpenDatabase(Database* database)
}
}
-void DatabaseTracker::getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet<RefPtr<Database>>* databases)
+void DatabaseTracker::getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet<RefPtr<DatabaseBackendBase>>* databases)
{
- LockHolder openDatabaseMapLock(m_openDatabaseMapGuard);
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
if (!m_openDatabaseMap)
return;
@@ -641,13 +636,13 @@ void DatabaseTracker::getOpenDatabases(SecurityOrigin* origin, const String& nam
if (!databaseSet)
return;
- for (auto& database : *databaseSet)
- databases->add(database);
+ for (DatabaseSet::iterator it = databaseSet->begin(); it != databaseSet->end(); ++it)
+ databases->add(*it);
}
-RefPtr<OriginLock> DatabaseTracker::originLockFor(SecurityOrigin* origin)
+PassRefPtr<OriginLock> DatabaseTracker::originLockFor(SecurityOrigin* origin)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
String databaseIdentifier = origin->databaseIdentifier();
// The originLockMap is accessed from multiple DatabaseThreads since
@@ -663,11 +658,11 @@ RefPtr<OriginLock> DatabaseTracker::originLockFor(SecurityOrigin* origin)
return addResult.iterator->value;
String path = originPath(origin);
- RefPtr<OriginLock> lock = adoptRef(*new OriginLock(path));
+ RefPtr<OriginLock> lock = adoptRef(new OriginLock(path));
ASSERT(lock);
addResult.iterator->value = lock;
- return lock;
+ return lock.release();
}
void DatabaseTracker::deleteOriginLockFor(SecurityOrigin* origin)
@@ -685,7 +680,8 @@ void DatabaseTracker::deleteOriginLockFor(SecurityOrigin* origin)
// files in this origin. We'll give the OriginLock one chance to do an
// orderly clean up first when we remove its ref from the m_originLockMap.
// This may or may not be possible depending on whether other threads are
- // also using the OriginLock at the same time. After that, we will delete the lock file.
+ // also using the OriginLock at the same time. After that, we will go ahead
+ // and delete the lock file.
m_originLockMap.remove(origin->databaseIdentifier());
OriginLock::deleteLockFile(originPath(origin));
@@ -695,9 +691,12 @@ unsigned long long DatabaseTracker::usageForOrigin(SecurityOrigin* origin)
{
String originPath = this->originPath(origin);
unsigned long long diskUsage = 0;
- for (auto& fileName : listDirectory(originPath, ASCIILiteral("*.db"))) {
+ Vector<String> fileNames = listDirectory(originPath, String("*.db"));
+ Vector<String>::iterator fileName = fileNames.begin();
+ Vector<String>::iterator lastFileName = fileNames.end();
+ for (; fileName != lastFileName; ++fileName) {
long long size;
- getFileSize(fileName, size);
+ getFileSize(*fileName, size);
diskUsage += size;
}
return diskUsage;
@@ -713,13 +712,13 @@ unsigned long long DatabaseTracker::quotaForOriginNoLock(SecurityOrigin* origin)
return quota;
SQLiteStatement statement(m_database, "SELECT quota FROM Origins where origin=?;");
- if (statement.prepare() != SQLITE_OK) {
+ if (statement.prepare() != SQLResultOk) {
LOG_ERROR("Failed to prepare statement.");
return quota;
}
statement.bindText(1, origin->databaseIdentifier());
- if (statement.step() == SQLITE_ROW)
+ if (statement.step() == SQLResultRow)
quota = statement.getColumnInt64(0);
return quota;
@@ -727,13 +726,13 @@ unsigned long long DatabaseTracker::quotaForOriginNoLock(SecurityOrigin* origin)
unsigned long long DatabaseTracker::quotaForOrigin(SecurityOrigin* origin)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
return quotaForOriginNoLock(origin);
}
void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota)
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
if (quotaForOriginNoLock(origin) == quota)
return;
@@ -749,13 +748,13 @@ void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota)
bool originEntryExists = hasEntryForOriginNoLock(origin);
if (!originEntryExists) {
SQLiteStatement statement(m_database, "INSERT INTO Origins VALUES (?, ?)");
- if (statement.prepare() != SQLITE_OK) {
+ if (statement.prepare() != SQLResultOk) {
LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data());
} else {
statement.bindText(1, origin->databaseIdentifier());
statement.bindInt64(2, quota);
- if (statement.step() != SQLITE_DONE)
+ if (statement.step() != SQLResultDone)
LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data());
#if PLATFORM(IOS)
else
@@ -764,7 +763,7 @@ void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota)
}
} else {
SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?");
- bool error = statement.prepare() != SQLITE_OK;
+ bool error = statement.prepare() != SQLResultOk;
if (!error) {
statement.bindInt64(1, quota);
statement.bindText(2, origin->databaseIdentifier());
@@ -800,7 +799,7 @@ bool DatabaseTracker::addDatabase(SecurityOrigin* origin, const String& name, co
SQLiteStatement statement(m_database, "INSERT INTO Databases (origin, name, path) VALUES (?, ?, ?);");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
return false;
statement.bindText(1, origin->databaseIdentifier());
@@ -823,39 +822,8 @@ void DatabaseTracker::deleteAllDatabases()
Vector<RefPtr<SecurityOrigin>> originsCopy;
origins(originsCopy);
- for (auto& origin : originsCopy)
- deleteOrigin(origin.get());
-}
-
-void DatabaseTracker::deleteDatabasesModifiedSince(std::chrono::system_clock::time_point time)
-{
- Vector<RefPtr<SecurityOrigin>> originsCopy;
- origins(originsCopy);
-
- for (auto& origin : originsCopy) {
- Vector<String> databaseNames;
- if (!databaseNamesForOrigin(origin.get(), databaseNames))
- continue;
-
- size_t deletedDatabases = 0;
-
- for (auto& databaseName : databaseNames) {
- auto fullPath = fullPathForDatabase(origin.get(), databaseName, false);
-
- time_t modificationTime;
- if (!getFileModificationTime(fullPath, modificationTime))
- continue;
-
- if (modificationTime < std::chrono::system_clock::to_time_t(time))
- continue;
-
- deleteDatabase(origin.get(), databaseName);
- ++deletedDatabases;
- }
-
- if (deletedDatabases == databaseNames.size())
- deleteOrigin(origin.get());
- }
+ for (unsigned i = 0; i < originsCopy.size(); ++i)
+ deleteOrigin(originsCopy[i].get());
}
// It is the caller's responsibility to make sure that nobody is trying to create, delete, open, or close databases in this origin while the deletion is
@@ -864,7 +832,7 @@ bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
{
Vector<String> databaseNames;
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
openTrackerDatabase(DontCreateIfDoesNotExist);
if (!m_database.isOpen())
return false;
@@ -882,20 +850,20 @@ bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
}
// We drop the lock here because holding locks during a call to deleteDatabaseFile will deadlock.
- for (auto& name : databaseNames) {
- if (!deleteDatabaseFile(origin, name)) {
+ for (unsigned i = 0; i < databaseNames.size(); ++i) {
+ if (!deleteDatabaseFile(origin, databaseNames[i])) {
// Even if the file can't be deleted, we want to try and delete the rest, don't return early here.
- LOG_ERROR("Unable to delete file for database %s in origin %s", name.ascii().data(), origin->databaseIdentifier().ascii().data());
+ LOG_ERROR("Unable to delete file for database %s in origin %s", databaseNames[i].ascii().data(), origin->databaseIdentifier().ascii().data());
}
}
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
deleteOriginLockFor(origin);
doneDeletingOrigin(origin);
SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=?");
- if (statement.prepare() != SQLITE_OK) {
+ if (statement.prepare() != SQLResultOk) {
LOG_ERROR("Unable to prepare deletion of databases from origin %s from tracker", origin->databaseIdentifier().ascii().data());
return false;
}
@@ -908,7 +876,7 @@ bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
}
SQLiteStatement originStatement(m_database, "DELETE FROM Origins WHERE origin=?");
- if (originStatement.prepare() != SQLITE_OK) {
+ if (originStatement.prepare() != SQLResultOk) {
LOG_ERROR("Unable to prepare deletion of origin %s from tracker", origin->databaseIdentifier().ascii().data());
return false;
}
@@ -928,9 +896,9 @@ bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
openTrackerDatabase(DontCreateIfDoesNotExist);
if (m_database.isOpen()) {
SQLiteStatement statement(m_database, "SELECT origin FROM Origins");
- if (statement.prepare() != SQLITE_OK)
+ if (statement.prepare() != SQLResultOk)
LOG_ERROR("Failed to prepare statement.");
- else if (statement.step() == SQLITE_ROW)
+ else if (statement.step() == SQLResultRow)
isEmpty = false;
}
@@ -947,8 +915,8 @@ bool DatabaseTracker::deleteOrigin(SecurityOrigin* origin)
#if PLATFORM(IOS)
m_client->dispatchDidDeleteDatabaseOrigin();
#endif
- for (auto& name : databaseNames)
- m_client->dispatchDidModifyDatabase(origin, name);
+ for (unsigned i = 0; i < databaseNames.size(); ++i)
+ m_client->dispatchDidModifyDatabase(origin, databaseNames[i]);
}
}
return true;
@@ -1071,7 +1039,7 @@ void DatabaseTracker::doneDeletingOrigin(SecurityOrigin *origin)
bool DatabaseTracker::deleteDatabase(SecurityOrigin* origin, const String& name)
{
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
openTrackerDatabase(DontCreateIfDoesNotExist);
if (!m_database.isOpen())
return false;
@@ -1086,15 +1054,15 @@ bool DatabaseTracker::deleteDatabase(SecurityOrigin* origin, const String& name)
// We drop the lock here because holding locks during a call to deleteDatabaseFile will deadlock.
if (!deleteDatabaseFile(origin, name)) {
LOG_ERROR("Unable to delete file for database %s in origin %s", name.ascii().data(), origin->databaseIdentifier().ascii().data());
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
doneDeletingDatabase(origin, name);
return false;
}
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=? AND name=?");
- if (statement.prepare() != SQLITE_OK) {
+ if (statement.prepare() != SQLResultOk) {
LOG_ERROR("Unable to prepare deletion of database %s from origin %s from tracker", name.ascii().data(), origin->databaseIdentifier().ascii().data());
doneDeletingDatabase(origin, name);
return false;
@@ -1131,18 +1099,18 @@ bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& n
#ifndef NDEBUG
{
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
ASSERT(isDeletingDatabaseOrOriginFor(origin, name));
}
#endif
- Vector<RefPtr<Database>> deletedDatabases;
+ Vector<RefPtr<DatabaseBackendBase>> deletedDatabases;
// Make sure not to hold the any locks when calling
// Database::markAsDeletedAndClose(), since that can cause a deadlock
// during the synchronous DatabaseThread call it triggers.
{
- LockHolder openDatabaseMapLock(m_openDatabaseMapGuard);
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
if (m_openDatabaseMap) {
// There are some open databases, lets check if they are for this origin.
DatabaseNameMap* nameMap = m_openDatabaseMap->get(origin);
@@ -1152,15 +1120,16 @@ bool DatabaseTracker::deleteDatabaseFile(SecurityOrigin* origin, const String& n
DatabaseSet* databaseSet = nameMap->get(name);
if (databaseSet && databaseSet->size()) {
// We have some database open with this name. Mark them as deleted.
- for (auto& database : *databaseSet)
- deletedDatabases.append(database);
+ DatabaseSet::const_iterator end = databaseSet->end();
+ for (DatabaseSet::const_iterator it = databaseSet->begin(); it != end; ++it)
+ deletedDatabases.append(*it);
}
}
}
}
- for (auto& database : deletedDatabases)
- database->markAsDeletedAndClose();
+ for (unsigned i = 0; i < deletedDatabases.size(); ++i)
+ deletedDatabases[i]->markAsDeletedAndClose();
#if !PLATFORM(IOS)
return SQLiteFileSystem::deleteDatabaseFile(fullPath);
@@ -1185,7 +1154,7 @@ void DatabaseTracker::removeDeletedOpenedDatabases()
{
// Acquire the lock before calling openTrackerDatabase.
- LockHolder lockDatabase(m_databaseGuard);
+ MutexLocker lockDatabase(m_databaseGuard);
openTrackerDatabase(DontCreateIfDoesNotExist);
}
@@ -1201,29 +1170,35 @@ void DatabaseTracker::removeDeletedOpenedDatabases()
// Database::markAsDeletedAndClose(), since that can cause a deadlock
// during the synchronous DatabaseThread call it triggers.
{
- LockHolder openDatabaseMapLock(m_openDatabaseMapGuard);
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
if (m_openDatabaseMap) {
- for (auto& openDatabase : *m_openDatabaseMap) {
- auto& origin = openDatabase.key;
- DatabaseNameMap* databaseNameMap = openDatabase.value;
+ DatabaseOriginMap::const_iterator originMapEnd = m_openDatabaseMap->end();
+ for (DatabaseOriginMap::const_iterator originMapIt = m_openDatabaseMap->begin(); originMapIt != originMapEnd; ++originMapIt) {
+ RefPtr<SecurityOrigin> origin = originMapIt->key;
+ DatabaseNameMap* databaseNameMap = originMapIt->value;
Vector<String> deletedDatabaseNamesForThisOrigin;
// Loop through all opened databases in this origin. Get the current database file path of each database and see if
// it still matches the path stored in the opened database object.
- for (auto& databases : *databaseNameMap) {
- String databaseName = databases.key;
+ DatabaseNameMap::const_iterator dbNameMapEnd = databaseNameMap->end();
+ for (DatabaseNameMap::const_iterator dbNameMapIt = databaseNameMap->begin(); dbNameMapIt != dbNameMapEnd; ++dbNameMapIt) {
+ String databaseName = dbNameMapIt->key;
String databaseFileName;
SQLiteStatement statement(m_database, "SELECT path FROM Databases WHERE origin=? AND name=?;");
- if (statement.prepare() == SQLITE_OK) {
+ if (statement.prepare() == SQLResultOk) {
statement.bindText(1, origin->databaseIdentifier());
statement.bindText(2, databaseName);
- if (statement.step() == SQLITE_ROW)
+ if (statement.step() == SQLResultRow)
databaseFileName = statement.getColumnText(0);
statement.finalize();
}
bool foundDeletedDatabase = false;
- for (auto& db : *databases.value) {
+ DatabaseSet* databaseSet = dbNameMapIt->value;
+ DatabaseSet::const_iterator dbEnd = databaseSet->end();
+ for (DatabaseSet::const_iterator dbIt = databaseSet->begin(); dbIt != dbEnd; ++dbIt) {
+ Database* db = static_cast<Database*>(*dbIt);
+
// We are done if this database has already been marked as deleted.
if (db->deleted())
continue;
@@ -1246,18 +1221,19 @@ void DatabaseTracker::removeDeletedOpenedDatabases()
}
}
- for (auto& deletedDatabase : deletedDatabases)
- deletedDatabase->markAsDeletedAndClose();
-
- for (auto& deletedDatabase : deletedDatabaseMap) {
- SecurityOrigin* origin = deletedDatabase.key.get();
+ for (unsigned i = 0; i < deletedDatabases.size(); ++i)
+ deletedDatabases[i]->markAsDeletedAndClose();
+
+ DeletedDatabaseMap::const_iterator end = deletedDatabaseMap.end();
+ for (DeletedDatabaseMap::const_iterator it = deletedDatabaseMap.begin(); it != end; ++it) {
+ SecurityOrigin* origin = it->key.get();
if (m_client)
m_client->dispatchDidModifyOrigin(origin);
- const Vector<String>& databaseNames = deletedDatabase.value;
- for (auto& databaseName : databaseNames) {
+ const Vector<String>& databaseNames = it->value;
+ for (unsigned i = 0; i < databaseNames.size(); ++i) {
if (m_client)
- m_client->dispatchDidModifyDatabase(origin, databaseName);
+ m_client->dispatchDidModifyDatabase(origin, databaseNames[i]);
}
}
}
@@ -1280,20 +1256,20 @@ bool DatabaseTracker::deleteDatabaseFileIfEmpty(const String& path)
// Specify that we want the exclusive locking mode, so after the next read,
// we'll be holding the lock to this database file.
SQLiteStatement lockStatement(database, "PRAGMA locking_mode=EXCLUSIVE;");
- if (lockStatement.prepare() != SQLITE_OK)
+ if (lockStatement.prepare() != SQLResultOk)
return false;
int result = lockStatement.step();
- if (result != SQLITE_ROW && result != SQLITE_DONE)
+ if (result != SQLResultRow && result != SQLResultDone)
return false;
lockStatement.finalize();
// Every sqlite database has a sqlite_master table that contains the schema for the database.
// http://www.sqlite.org/faq.html#q7
SQLiteStatement readStatement(database, "SELECT * FROM sqlite_master LIMIT 1;");
- if (readStatement.prepare() != SQLITE_OK)
+ if (readStatement.prepare() != SQLResultOk)
return false;
// We shouldn't expect any result.
- if (readStatement.step() != SQLITE_DONE)
+ if (readStatement.step() != SQLResultDone)
return false;
readStatement.finalize();
@@ -1305,9 +1281,9 @@ bool DatabaseTracker::deleteDatabaseFileIfEmpty(const String& path)
return SQLiteFileSystem::deleteDatabaseFile(path);
}
-Lock& DatabaseTracker::openDatabaseMutex()
+Mutex& DatabaseTracker::openDatabaseMutex()
{
- static NeverDestroyed<Lock> mutex;
+ DEFINE_STATIC_LOCAL(Mutex, mutex, ());
return mutex;
}
@@ -1323,6 +1299,33 @@ void DatabaseTracker::emptyDatabaseFilesRemovalTaskDidFinish()
openDatabaseMutex().unlock();
}
+void DatabaseTracker::setDatabasesPaused(bool paused)
+{
+ MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);
+ if (!m_openDatabaseMap)
+ return;
+
+ // This walking is - sadly - the only reliable way to get at each open database thread.
+ // This will be cleaner once <rdar://problem/5680441> or some other DB thread consolidation takes place.
+ DatabaseOriginMap::iterator i = m_openDatabaseMap.get()->begin();
+ DatabaseOriginMap::iterator end = m_openDatabaseMap.get()->end();
+
+ for (; i != end; ++i) {
+ DatabaseNameMap* databaseNameMap = i->value;
+ DatabaseNameMap::iterator j = databaseNameMap->begin();
+ DatabaseNameMap::iterator dbNameMapEnd = databaseNameMap->end();
+ for (; j != dbNameMapEnd; ++j) {
+ DatabaseSet* databaseSet = j->value;
+ DatabaseSet::iterator k = databaseSet->begin();
+ DatabaseSet::iterator dbSetEnd = databaseSet->end();
+ for (; k != dbSetEnd; ++k) {
+ DatabaseContext* context = (*k)->databaseContext();
+ context->setPaused(paused);
+ }
+ }
+ }
+}
+
#endif
void DatabaseTracker::setClient(DatabaseManagerClient* client)
@@ -1330,9 +1333,9 @@ void DatabaseTracker::setClient(DatabaseManagerClient* client)
m_client = client;
}
-static Lock& notificationMutex()
+static Mutex& notificationMutex()
{
- static NeverDestroyed<Lock> mutex;
+ DEFINE_STATIC_LOCAL(Mutex, mutex, ());
return mutex;
}
@@ -1340,13 +1343,13 @@ typedef Vector<std::pair<RefPtr<SecurityOrigin>, String>> NotificationQueue;
static NotificationQueue& notificationQueue()
{
- static NeverDestroyed<NotificationQueue> queue;
+ DEFINE_STATIC_LOCAL(NotificationQueue, queue, ());
return queue;
}
void DatabaseTracker::scheduleNotifyDatabaseChanged(SecurityOrigin* origin, const String& name)
{
- LockHolder locker(notificationMutex());
+ MutexLocker locker(notificationMutex());
notificationQueue().append(std::pair<RefPtr<SecurityOrigin>, String>(origin->isolatedCopy(), name.isolatedCopy()));
scheduleForNotification();
@@ -1359,14 +1362,12 @@ void DatabaseTracker::scheduleForNotification()
ASSERT(!notificationMutex().tryLock());
if (!notificationScheduled) {
- callOnMainThread([] {
- notifyDatabasesChanged();
- });
+ callOnMainThread(DatabaseTracker::notifyDatabasesChanged, 0);
notificationScheduled = true;
}
}
-void DatabaseTracker::notifyDatabasesChanged()
+void DatabaseTracker::notifyDatabasesChanged(void*)
{
// Note that if DatabaseTracker ever becomes non-singleton, we'll have to amend this notification
// mechanism to include which tracker the notification goes out on as well.
@@ -1374,7 +1375,7 @@ void DatabaseTracker::notifyDatabasesChanged()
NotificationQueue notifications;
{
- LockHolder locker(notificationMutex());
+ MutexLocker locker(notificationMutex());
notifications.swap(notificationQueue());
@@ -1390,3 +1391,4 @@ void DatabaseTracker::notifyDatabasesChanged()
} // namespace WebCore
+#endif