diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/storage')
50 files changed, 772 insertions, 345 deletions
diff --git a/src/3rdparty/webkit/WebCore/storage/ChangeVersionWrapper.cpp b/src/3rdparty/webkit/WebCore/storage/ChangeVersionWrapper.cpp index a2be615..33660e7 100644 --- a/src/3rdparty/webkit/WebCore/storage/ChangeVersionWrapper.cpp +++ b/src/3rdparty/webkit/WebCore/storage/ChangeVersionWrapper.cpp @@ -42,21 +42,21 @@ ChangeVersionWrapper::ChangeVersionWrapper(const String& oldVersion, const Strin bool ChangeVersionWrapper::performPreflight(SQLTransaction* transaction) { ASSERT(transaction && transaction->database()); - + String actualVersion; - + if (!transaction->database()->getVersionFromDatabase(actualVersion)) { LOG_ERROR("Unable to retrieve actual current version from database"); m_sqlError = SQLError::create(0, "unable to verify current version of database"); return false; } - + if (actualVersion != m_oldVersion) { LOG_ERROR("Old version doesn't match actual version"); m_sqlError = SQLError::create(2, "current version of the database and `oldVersion` argument do not match"); return false; } - + return true; } @@ -71,10 +71,10 @@ bool ChangeVersionWrapper::performPostflight(SQLTransaction* transaction) } transaction->database()->setExpectedVersion(m_newVersion); - + return true; } - + } // namespace WebCore #endif // ENABLE(DATABASE) diff --git a/src/3rdparty/webkit/WebCore/storage/Database.cpp b/src/3rdparty/webkit/WebCore/storage/Database.cpp index 2292a0a..be0c490 100644 --- a/src/3rdparty/webkit/WebCore/storage/Database.cpp +++ b/src/3rdparty/webkit/WebCore/storage/Database.cpp @@ -50,6 +50,8 @@ #include "SQLiteFileSystem.h" #include "SQLiteStatement.h" #include "SQLResultSet.h" +#include "SQLTransactionClient.h" +#include "SQLTransactionCoordinator.h" #include <wtf/MainThread.h> #endif @@ -109,20 +111,22 @@ PassRefPtr<Database> Database::openDatabase(Document* document, const String& na LOG(StorageAPI, "Database %s for origin %s not allowed to be established", name.ascii().data(), document->securityOrigin()->toString().ascii().data()); return 0; } - + RefPtr<Database> database = adoptRef(new Database(document, name, expectedVersion)); if (!database->openAndVerifyVersion(e)) { LOG(StorageAPI, "Failed to open and verify version (expected %s) of database %s", expectedVersion.ascii().data(), database->databaseDebugName().ascii().data()); return 0; } - + DatabaseTracker::tracker().setDatabaseDetails(document->securityOrigin(), name, displayName, estimatedSize); document->setHasOpenDatabases(); +#if ENABLE(INSPECTOR) if (Page* page = document->frame()->page()) page->inspectorController()->didOpenDatabase(database.get(), document->securityOrigin()->host(), name, expectedVersion); +#endif return database; } @@ -292,7 +296,7 @@ bool Database::versionMatchesExpected() const MutexLocker locker(guidMutex()); return m_expectedVersion == guidToVersionMap().get(m_guid); } - + return true; } @@ -334,8 +338,8 @@ void Database::stop() // FIXME: The net effect of the following code is to remove all pending transactions and statements, but allow the current statement // to run to completion. In the future we can use the sqlite3_progress_handler or sqlite3_interrupt interfaces to cancel the current // statement in response to close(), as well. - - // This method is meant to be used as an analog to cancelling a loader, and is used when a document is shut down as the result of + + // This method is meant to be used as an analog to cancelling a loader, and is used when a document is shut down as the result of // a page load or closing the page m_stopped = true; @@ -355,10 +359,10 @@ unsigned long long Database::maximumSize() const { // The maximum size for this database is the full quota for this origin, minus the current usage within this origin, // except for the current usage of this database - + OriginQuotaManager& manager(DatabaseTracker::tracker().originQuotaManager()); Locker<OriginQuotaManager> locker(manager); - + return DatabaseTracker::tracker().quotaForOrigin(m_securityOrigin.get()) - manager.diskUsage(m_securityOrigin.get()) + databaseSize(); } @@ -441,14 +445,6 @@ bool Database::performOpenAndVerify(ExceptionCode& e) m_sqliteDatabase.setAuthorizer(m_databaseAuthorizer); m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); - if (!m_sqliteDatabase.tableExists(databaseInfoTableName())) { - if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + databaseInfoTableName() + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) { - LOG_ERROR("Unable to create table %s in database %s", databaseInfoTableName().ascii().data(), databaseDebugName().ascii().data()); - e = INVALID_STATE_ERR; - return false; - } - } - String currentVersion; { MutexLocker locker(guidMutex()); @@ -466,6 +462,15 @@ bool Database::performOpenAndVerify(ExceptionCode& e) LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data()); } else { LOG(StorageAPI, "No cached version for guid %i", m_guid); + + if (!m_sqliteDatabase.tableExists(databaseInfoTableName())) { + if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + databaseInfoTableName() + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) { + LOG_ERROR("Unable to create table %s in database %s", databaseInfoTableName().ascii().data(), databaseDebugName().ascii().data()); + e = INVALID_STATE_ERR; + return false; + } + } + if (!getVersionFromDatabase(currentVersion)) { LOG_ERROR("Failed to get current version from database %s", databaseDebugName().ascii().data()); e = INVALID_STATE_ERR; @@ -507,7 +512,7 @@ bool Database::performOpenAndVerify(ExceptionCode& e) return true; } -void Database::changeVersion(const String& oldVersion, const String& newVersion, +void Database::changeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback) { @@ -518,9 +523,9 @@ void Database::changeVersion(const String& oldVersion, const String& newVersion, } void Database::transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, - PassRefPtr<VoidCallback> successCallback) + PassRefPtr<VoidCallback> successCallback, bool readOnly) { - m_transactionQueue.append(SQLTransaction::create(this, callback, errorCallback, successCallback, 0)); + m_transactionQueue.append(SQLTransaction::create(this, callback, errorCallback, successCallback, 0, readOnly)); MutexLocker locker(m_transactionInProgressMutex); if (!m_transactionInProgress) scheduleTransaction(); @@ -539,13 +544,17 @@ void Database::scheduleTransaction() m_transactionInProgress = false; } -void Database::scheduleTransactionStep(SQLTransaction* transaction) +void Database::scheduleTransactionStep(SQLTransaction* transaction, bool immediately) { - if (m_document->databaseThread()) { - RefPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); - LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get()); + if (!m_document->databaseThread()) + return; + + RefPtr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); + LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get()); + if (immediately) + m_document->databaseThread()->scheduleImmediateTask(task.release()); + else m_document->databaseThread()->scheduleTask(task.release()); - } } void Database::scheduleTransactionCallback(SQLTransaction* transaction) @@ -583,6 +592,16 @@ Vector<String> Database::performGetTableNames() return tableNames; } +SQLTransactionClient* Database::transactionClient() const +{ + return m_document->databaseThread()->transactionClient(); +} + +SQLTransactionCoordinator* Database::transactionCoordinator() const +{ + return m_document->databaseThread()->transactionCoordinator(); +} + String Database::version() const { if (m_deleted) diff --git a/src/3rdparty/webkit/WebCore/storage/Database.h b/src/3rdparty/webkit/WebCore/storage/Database.h index 0bdb37b..b850686 100644 --- a/src/3rdparty/webkit/WebCore/storage/Database.h +++ b/src/3rdparty/webkit/WebCore/storage/Database.h @@ -41,7 +41,6 @@ #include <wtf/Forward.h> #include <wtf/HashSet.h> -#include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/Deque.h> @@ -57,9 +56,11 @@ class DatabaseThread; class Document; class SQLResultSet; class SQLTransactionCallback; +class SQLTransactionClient; +class SQLTransactionCoordinator; class SQLTransactionErrorCallback; class SQLValue; - + typedef int ExceptionCode; class Database : public ThreadSafeShared<Database> { @@ -72,12 +73,12 @@ public: // Direct support for the DOM API static PassRefPtr<Database> openDatabase(Document* document, const String& name, const String& expectedVersion, const String& displayName, unsigned long estimatedSize, ExceptionCode&); String version() const; - void changeVersion(const String& oldVersion, const String& newVersion, + void changeVersion(const String& oldVersion, const String& newVersion, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback); void transaction(PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, - PassRefPtr<VoidCallback> successCallback); - + PassRefPtr<VoidCallback> successCallback, bool readOnly); + // Internal engine support static const String& databaseInfoTableName(); @@ -90,7 +91,7 @@ public: Document* document() const { return m_document.get(); } PassRefPtr<SecurityOrigin> securityOriginCopy() const; String stringIdentifier() const; - + bool getVersionFromDatabase(String&); bool setVersionInDatabase(const String&); void setExpectedVersion(const String&); @@ -101,7 +102,7 @@ public: void close(); bool opened() const { return m_opened; } - + void stop(); bool stopped() const { return m_stopped; } @@ -116,6 +117,9 @@ public: Vector<String> performGetTableNames(); + SQLTransactionClient* transactionClient() const; + SQLTransactionCoordinator* transactionCoordinator() const; + private: Database(Document* document, const String& name, const String& expectedVersion); @@ -123,8 +127,8 @@ private: void scheduleTransaction(); void scheduleTransactionCallback(SQLTransaction*); - void scheduleTransactionStep(SQLTransaction* transaction); - + void scheduleTransactionStep(SQLTransaction* transaction, bool immediately = false); + MessageQueue<RefPtr<SQLTransaction> > m_transactionQueue; Mutex m_transactionInProgressMutex; bool m_transactionInProgress; @@ -139,7 +143,7 @@ private: String m_filename; bool m_deleted; - + bool m_stopped; bool m_opened; diff --git a/src/3rdparty/webkit/WebCore/storage/Database.idl b/src/3rdparty/webkit/WebCore/storage/Database.idl index 1e4b316..6ca9c95 100644 --- a/src/3rdparty/webkit/WebCore/storage/Database.idl +++ b/src/3rdparty/webkit/WebCore/storage/Database.idl @@ -34,6 +34,7 @@ module storage { readonly attribute DOMString version; [Custom] void changeVersion(in DOMString oldVersion, in DOMString newVersion, in SQLTransactionCallback callback, in SQLTransactionErrorCallback errorCallback, in VoidCallback successCallback); [Custom] void transaction(in SQLTransactionCallback callback, in SQLTransactionErrorCallback errorCallback, in VoidCallback successCallback); + [Custom] void readTransaction(in SQLTransactionCallback callback, in SQLTransactionErrorCallback errorCallback, in VoidCallback successCallback); }; } diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.cpp b/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.cpp index 2d182ce..93f9106 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.cpp +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.cpp @@ -58,6 +58,12 @@ int DatabaseAuthorizer::createTable(const String& tableName) int DatabaseAuthorizer::createTempTable(const String& tableName) { + // SQLITE_CREATE_TEMP_TABLE results in a UPDATE operation, which is not + // allowed in read-only transactions or private browsing, so we might as + // well disallow SQLITE_CREATE_TEMP_TABLE in these cases + if (m_readOnly && m_securityEnabled) + return SQLAuthDeny; + return denyBasedOnTableName(tableName); } @@ -71,6 +77,12 @@ int DatabaseAuthorizer::dropTable(const String& tableName) int DatabaseAuthorizer::dropTempTable(const String& tableName) { + // SQLITE_DROP_TEMP_TABLE results in a DELETE operation, which is not + // allowed in read-only transactions or private browsing, so we might as + // well disallow SQLITE_DROP_TEMP_TABLE in these cases + if (m_readOnly && m_securityEnabled) + return SQLAuthDeny; + return denyBasedOnTableName(tableName); } @@ -94,6 +106,12 @@ int DatabaseAuthorizer::createIndex(const String&, const String& tableName) int DatabaseAuthorizer::createTempIndex(const String&, const String& tableName) { + // SQLITE_CREATE_TEMP_INDEX should result in a UPDATE or INSERT operation, + // which is not allowed in read-only transactions or private browsing, + // so we might as well disallow SQLITE_CREATE_TEMP_INDEX in these cases + if (m_readOnly && m_securityEnabled) + return SQLAuthDeny; + return denyBasedOnTableName(tableName); } @@ -107,6 +125,12 @@ int DatabaseAuthorizer::dropIndex(const String&, const String& tableName) int DatabaseAuthorizer::dropTempIndex(const String&, const String& tableName) { + // SQLITE_DROP_TEMP_INDEX should result in a DELETE operation, which is + // not allowed in read-only transactions or private browsing, so we might + // as well disallow SQLITE_DROP_TEMP_INDEX in these cases + if (m_readOnly && m_securityEnabled) + return SQLAuthDeny; + return denyBasedOnTableName(tableName); } @@ -121,6 +145,12 @@ int DatabaseAuthorizer::createTrigger(const String&, const String& tableName) int DatabaseAuthorizer::createTempTrigger(const String&, const String& tableName) { + // SQLITE_CREATE_TEMP_TRIGGER results in a INSERT operation, which is not + // allowed in read-only transactions or private browsing, so we might as + // well disallow SQLITE_CREATE_TEMP_TRIGGER in these cases + if (m_readOnly && m_securityEnabled) + return SQLAuthDeny; + return denyBasedOnTableName(tableName); } @@ -134,9 +164,41 @@ int DatabaseAuthorizer::dropTrigger(const String&, const String& tableName) int DatabaseAuthorizer::dropTempTrigger(const String&, const String& tableName) { + // SQLITE_DROP_TEMP_TRIGGER results in a DELETE operation, which is not + // allowed in read-only transactions or private browsing, so we might as + // well disallow SQLITE_DROP_TEMP_TRIGGER in these cases + if (m_readOnly && m_securityEnabled) + return SQLAuthDeny; + return denyBasedOnTableName(tableName); } +int DatabaseAuthorizer::createView(const String&) +{ + return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow); +} + +int DatabaseAuthorizer::createTempView(const String&) +{ + // SQLITE_CREATE_TEMP_VIEW results in a UPDATE operation, which is not + // allowed in read-only transactions or private browsing, so we might as + // well disallow SQLITE_CREATE_TEMP_VIEW in these cases + return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow); +} + +int DatabaseAuthorizer::dropView(const String&) +{ + return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow); +} + +int DatabaseAuthorizer::dropTempView(const String&) +{ + // SQLITE_DROP_TEMP_VIEW results in a DELETE operation, which is not + // allowed in read-only transactions or private browsing, so we might as + // well disallow SQLITE_DROP_TEMP_VIEW in these cases + return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow); +} + int DatabaseAuthorizer::createVTable(const String&, const String&) { if (m_readOnly && m_securityEnabled) @@ -191,6 +253,11 @@ int DatabaseAuthorizer::allowRead(const String& tableName, const String&) return denyBasedOnTableName(tableName); } +int DatabaseAuthorizer::allowReindex(const String&) +{ + return (m_readOnly && m_securityEnabled ? SQLAuthDeny : SQLAuthAllow); +} + int DatabaseAuthorizer::allowAnalyze(const String& tableName) { return denyBasedOnTableName(tableName); diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.h b/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.h index e53ea50..248b659 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.h +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.h @@ -59,10 +59,10 @@ public: int dropTrigger(const String& triggerName, const String& tableName); int dropTempTrigger(const String& triggerName, const String& tableName); - int createView(const String& /*viewName*/) { return SQLAuthAllow; } - int createTempView(const String& /*viewName*/) { return SQLAuthAllow; } - int dropView(const String& /*viewName*/) { return SQLAuthAllow; } - int dropTempView(const String& /*viewName*/) { return SQLAuthAllow; } + int createView(const String& viewName); + int createTempView(const String& viewName); + int dropView(const String& viewName); + int dropTempView(const String& viewName); int createVTable(const String& tableName, const String& moduleName); int dropVTable(const String& tableName, const String& moduleName); @@ -75,7 +75,7 @@ public: int allowSelect() { return SQLAuthAllow; } int allowRead(const String& tableName, const String& columnName); - int allowReindex(const String& /*indexName*/) { return SQLAuthAllow; } + int allowReindex(const String& indexName); int allowAnalyze(const String& tableName); int allowFunction(const String& functionName); int allowPragma(const String& pragmaName, const String& firstArgument); diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseDetails.h b/src/3rdparty/webkit/WebCore/storage/DatabaseDetails.h index a4d85fd..9b0f506 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseDetails.h +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseDetails.h @@ -60,7 +60,7 @@ private: String m_name; String m_displayName; unsigned long long m_expectedUsage; - unsigned long long m_currentUsage; + unsigned long long m_currentUsage; }; diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp index b6c9b5d..9e3afdd 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp @@ -35,11 +35,15 @@ #include "Database.h" #include "DatabaseTask.h" #include "Logging.h" +#include "SQLTransactionClient.h" +#include "SQLTransactionCoordinator.h" namespace WebCore { DatabaseThread::DatabaseThread() : m_threadID(0) + , m_transactionClient(new SQLTransactionClient()) + , m_transactionCoordinator(new SQLTransactionCoordinator()) { m_selfRef = this; } @@ -97,6 +101,9 @@ void* DatabaseThread::databaseThread() pool.cycle(); } + // Clean up the list of all pending transactions on this database thread + m_transactionCoordinator->shutdown(); + LOG(StorageAPI, "About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)", m_threadID, this, refCount()); // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an @@ -119,7 +126,7 @@ void* DatabaseThread::databaseThread() return 0; } -void DatabaseThread::recordDatabaseOpen(Database* database) +void DatabaseThread::recordDatabaseOpen(Database* database) { ASSERT(currentThread() == m_threadID); ASSERT(database); @@ -127,7 +134,7 @@ void DatabaseThread::recordDatabaseOpen(Database* database) m_openDatabaseSet.add(database); } -void DatabaseThread::recordDatabaseClosed(Database* database) +void DatabaseThread::recordDatabaseClosed(Database* database) { ASSERT(currentThread() == m_threadID); ASSERT(database); diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h index 5aab5fd..83b1baf 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseThread.h @@ -33,6 +33,7 @@ #include <wtf/HashMap.h> #include <wtf/HashSet.h> #include <wtf/MessageQueue.h> +#include <wtf/OwnPtr.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/Threading.h> @@ -42,6 +43,8 @@ namespace WebCore { class Database; class DatabaseTask; class Document; +class SQLTransactionClient; +class SQLTransactionCoordinator; class DatabaseThread : public ThreadSafeShared<DatabaseThread> { public: @@ -60,6 +63,9 @@ public: void recordDatabaseClosed(Database*); ThreadIdentifier getThreadID() { return m_threadID; } + SQLTransactionClient* transactionClient() { return m_transactionClient.get(); } + SQLTransactionCoordinator* transactionCoordinator() { return m_transactionCoordinator.get(); } + private: DatabaseThread(); @@ -75,6 +81,9 @@ private: // This set keeps track of the open databases that have been used on this thread. typedef HashSet<RefPtr<Database> > DatabaseSet; DatabaseSet m_openDatabaseSet; + + OwnPtr<SQLTransactionClient> m_transactionClient; + OwnPtr<SQLTransactionCoordinator> m_transactionCoordinator; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp b/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp index e7c9485..491e6f1 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp @@ -131,7 +131,7 @@ bool DatabaseTracker::canEstablishDatabase(Document* document, const String& nam // Since we're imminently opening a database within this Document's origin, make sure this origin is being tracked by the QuotaTracker // by fetching it's current usage now unsigned long long usage = usageForOrigin(origin); - + // If a database already exists, ignore the passed-in estimated size and say it's OK. if (hasEntryForDatabase(origin, name)) return true; @@ -197,11 +197,11 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String String originIdentifier = origin->databaseIdentifier(); String originPath = this->originPath(origin); - + // Make sure the path for this SecurityOrigin exists if (createIfNotExists && !SQLiteFileSystem::ensureDatabaseDirectoryExists(originPath)) return String(); - + // See if we have a path for this database yet openTrackerDatabase(false); if (!m_database.isOpen()) @@ -220,14 +220,14 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String return SQLiteFileSystem::appendDatabaseFileNameToPath(originPath, statement.getColumnText(0)); if (!createIfNotExists) return String(); - + if (result != SQLResultDone) { LOG_ERROR("Failed to retrieve filename from Database Tracker for origin %s, name %s", origin->databaseIdentifier().ascii().data(), name.ascii().data()); return String(); } statement.finalize(); - - String fileName = SQLiteFileSystem::getFileNameForNewDatabase(originPath, origin->databaseIdentifier(), name, &m_database); + + String fileName = SQLiteFileSystem::getFileNameForNewDatabase(originPath, name, origin->databaseIdentifier(), &m_database); if (!addDatabase(origin, name, fileName)) return String(); @@ -239,7 +239,7 @@ String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String if (originQuotaManager().tracksOrigin(origin)) originQuotaManager().addDatabase(origin, name, fullFilePath); } - + return fullFilePath; } @@ -321,19 +321,19 @@ DatabaseDetails DatabaseTracker::detailsForNameAndOrigin(const String& name, Sec SQLiteStatement statement(m_database, "SELECT displayName, estimatedSize FROM Databases WHERE origin=? AND name=?"); if (statement.prepare() != SQLResultOk) return DatabaseDetails(); - + statement.bindText(1, originIdentifier); statement.bindText(2, name); - + int result = statement.step(); if (result == SQLResultDone) return DatabaseDetails(); - + 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(); } - + return DatabaseDetails(name, statement.getColumnText(0), statement.getColumnInt64(1), usageForDatabase(name, origin)); } @@ -343,17 +343,17 @@ void DatabaseTracker::setDatabaseDetails(SecurityOrigin* origin, const String& n String originIdentifier = origin->databaseIdentifier(); int64_t guid = 0; - + openTrackerDatabase(true); if (!m_database.isOpen()) return; SQLiteStatement statement(m_database, "SELECT guid FROM Databases WHERE origin=? AND name=?"); if (statement.prepare() != SQLResultOk) return; - + statement.bindText(1, originIdentifier); statement.bindText(2, name); - + int result = statement.step(); if (result == SQLResultRow) guid = statement.getColumnInt64(0); @@ -371,20 +371,20 @@ void DatabaseTracker::setDatabaseDetails(SecurityOrigin* origin, const String& n } return; } - + SQLiteStatement updateStatement(m_database, "UPDATE Databases SET displayName=?, estimatedSize=? WHERE guid=?"); if (updateStatement.prepare() != SQLResultOk) return; - + updateStatement.bindText(1, displayName); updateStatement.bindInt64(2, estimatedSize); updateStatement.bindInt64(3, guid); - + if (updateStatement.step() != SQLResultDone) { LOG_ERROR("Failed to update details for database %s in origin %s", name.ascii().data(), originIdentifier.ascii().data()); - return; + return; } - + if (m_client) m_client->dispatchDidModifyDatabase(origin, name); } @@ -395,7 +395,7 @@ unsigned long long DatabaseTracker::usageForDatabase(const String& name, Securit String path = fullPathForDatabase(origin, name, false); if (path.isEmpty()) return 0; - + return SQLiteFileSystem::getDatabaseFileSize(path); } @@ -481,16 +481,16 @@ unsigned long long DatabaseTracker::usageForOrigin(SecurityOrigin* origin) // Use the OriginQuotaManager mechanism to calculate the usage if (originQuotaManager().tracksOrigin(origin)) return originQuotaManager().diskUsage(origin); - + // If the OriginQuotaManager doesn't track this origin already, prime it to do so originQuotaManager().trackOrigin(origin); - + Vector<String> names; databaseNamesForOrigin(origin, names); for (unsigned i = 0; i < names.size(); ++i) originQuotaManager().addDatabase(origin, names[i], fullPathForDatabase(origin, names[i], false)); - + if (!originQuotaManager().tracksOrigin(origin)) return 0; return originQuotaManager().diskUsage(origin); @@ -529,7 +529,7 @@ void DatabaseTracker::setQuota(SecurityOrigin* origin, unsigned long long quota) LOG_ERROR("Unable to establish origin %s in the tracker", origin->databaseIdentifier().ascii().data()); } } else { - SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?"); + SQLiteStatement statement(m_database, "UPDATE Origins SET quota=? WHERE origin=?"); bool error = statement.prepare() != SQLResultOk; if (!error) { statement.bindInt64(1, quota); @@ -556,7 +556,7 @@ bool DatabaseTracker::addDatabase(SecurityOrigin* origin, const String& name, co openTrackerDatabase(true); if (!m_database.isOpen()) return false; - + // New database should never be added until the origin has been established ASSERT(hasEntryForOrigin(origin)); @@ -573,10 +573,10 @@ bool DatabaseTracker::addDatabase(SecurityOrigin* origin, const String& name, co LOG_ERROR("Failed to add database %s to origin %s: %s\n", name.ascii().data(), origin->databaseIdentifier().ascii().data(), m_database.lastErrorMsg()); return false; } - + if (m_client) m_client->dispatchDidModifyOrigin(origin); - + return true; } @@ -603,27 +603,27 @@ void DatabaseTracker::deleteOrigin(SecurityOrigin* origin) LOG_ERROR("Unable to retrieve list of database names for origin %s", origin->databaseIdentifier().ascii().data()); return; } - + 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", databaseNames[i].ascii().data(), origin->databaseIdentifier().ascii().data()); - return; } } - + SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=?"); if (statement.prepare() != SQLResultOk) { LOG_ERROR("Unable to prepare deletion of databases from origin %s from tracker", origin->databaseIdentifier().ascii().data()); return; } - + statement.bindText(1, origin->databaseIdentifier()); - + if (!statement.executeCommand()) { LOG_ERROR("Unable to execute deletion of databases from origin %s from tracker", origin->databaseIdentifier().ascii().data()); return; } - + SQLiteStatement originStatement(m_database, "DELETE FROM Origins WHERE origin=?"); if (originStatement.prepare() != SQLResultOk) { LOG_ERROR("Unable to prepare deletion of origin %s from tracker", origin->databaseIdentifier().ascii().data()); @@ -631,7 +631,7 @@ void DatabaseTracker::deleteOrigin(SecurityOrigin* origin) } originStatement.bindText(1, origin->databaseIdentifier()); - + if (!originStatement.executeCommand()) { LOG_ERROR("Unable to execute deletion of databases from origin %s from tracker", origin->databaseIdentifier().ascii().data()); return; @@ -674,26 +674,26 @@ void DatabaseTracker::deleteDatabase(SecurityOrigin* origin, const String& name) LOG_ERROR("Unable to delete file for database %s in origin %s", name.ascii().data(), origin->databaseIdentifier().ascii().data()); return; } - + SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=? AND name=?"); 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()); return; } - + statement.bindText(1, origin->databaseIdentifier()); statement.bindText(2, name); - + if (!statement.executeCommand()) { LOG_ERROR("Unable to execute deletion of database %s from origin %s from tracker", name.ascii().data(), origin->databaseIdentifier().ascii().data()); return; } - + { Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); originQuotaManager().removeDatabase(origin, name); } - + if (m_client) { m_client->dispatchDidModifyOrigin(origin); m_client->dispatchDidModifyDatabase(origin, name); diff --git a/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.h b/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.h index dc50965..2f6e06d 100644 --- a/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.h +++ b/src/3rdparty/webkit/WebCore/storage/DatabaseTracker.h @@ -70,18 +70,18 @@ public: unsigned long long usageForOrigin(SecurityOrigin*); unsigned long long quotaForOrigin(SecurityOrigin*); void setQuota(SecurityOrigin*, unsigned long long); - + void deleteAllDatabases(); void deleteOrigin(SecurityOrigin*); void deleteDatabase(SecurityOrigin*, const String& name); void setClient(DatabaseTrackerClient*); - + // From a secondary thread, must be thread safe with its data void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name); - + OriginQuotaManager& originQuotaManager(); - + static DatabaseTracker& tracker(); bool hasEntryForOrigin(SecurityOrigin*); @@ -93,12 +93,12 @@ private: void openTrackerDatabase(bool createIfDoesNotExist); String originPath(SecurityOrigin*) const; - + bool hasEntryForDatabase(SecurityOrigin*, const String& databaseIdentifier); - + bool addDatabase(SecurityOrigin*, const String& name, const String& path); void populateOrigins(); - + bool deleteDatabaseFile(SecurityOrigin*, const String& name); SQLiteDatabase m_database; @@ -117,7 +117,7 @@ private: OwnPtr<OriginQuotaManager> m_quotaManager; String m_databaseDirectoryPath; - + DatabaseTrackerClient* m_client; std::pair<SecurityOrigin*, DatabaseDetails>* m_proposedDatabase; diff --git a/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.cpp b/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.cpp index f5d4890..4cea845 100644 --- a/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.cpp +++ b/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -73,4 +73,3 @@ void LocalStorageTask::performTask() } #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.h b/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.h index b12a26b..726b41f 100644 --- a/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.h +++ b/src/3rdparty/webkit/WebCore/storage/LocalStorageTask.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LocalStorageTask_h diff --git a/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.cpp b/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.cpp index 2da5934..c85d5e6 100644 --- a/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.cpp +++ b/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -101,7 +101,7 @@ void LocalStorageThread::scheduleSync(PassRefPtr<StorageAreaSync> area) void LocalStorageThread::terminate() { ASSERT(isMainThread()); - + // Ideally we'd never be killing a thread that wasn't live, so ASSERT it. // But if we do in a release build, make sure to not wait on a condition that will never get signalled ASSERT(!m_queue.killed() && m_threadID); @@ -109,9 +109,9 @@ void LocalStorageThread::terminate() return; MutexLocker locker(m_terminateLock); - + m_queue.append(LocalStorageTask::createTerminate(this)); - + m_terminateCondition.wait(m_terminateLock); } @@ -120,7 +120,7 @@ void LocalStorageThread::performTerminate() ASSERT(!isMainThread()); m_queue.kill(); - + MutexLocker locker(m_terminateLock); m_terminateCondition.signal(); } @@ -128,4 +128,3 @@ void LocalStorageThread::performTerminate() } #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.h b/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.h index 3d58427..b903fb9 100644 --- a/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.h +++ b/src/3rdparty/webkit/WebCore/storage/LocalStorageThread.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef LocalStorageThread_h @@ -64,7 +64,7 @@ namespace WebCore { RefPtr<LocalStorageThread> m_selfRef; MessageQueue<RefPtr<LocalStorageTask> > m_queue; - + Mutex m_terminateLock; ThreadCondition m_terminateCondition; }; diff --git a/src/3rdparty/webkit/WebCore/storage/OriginQuotaManager.cpp b/src/3rdparty/webkit/WebCore/storage/OriginQuotaManager.cpp index 2b98ab7..b757f70 100644 --- a/src/3rdparty/webkit/WebCore/storage/OriginQuotaManager.cpp +++ b/src/3rdparty/webkit/WebCore/storage/OriginQuotaManager.cpp @@ -75,25 +75,25 @@ bool OriginQuotaManager::tracksOrigin(SecurityOrigin* origin) const void OriginQuotaManager::addDatabase(SecurityOrigin* origin, const String& databaseIdentifier, const String& fullPath) { ASSERT(m_usageRecordGuardLocked); - + OriginUsageRecord* usageRecord = m_usageMap.get(origin); ASSERT(usageRecord); - + usageRecord->addDatabase(databaseIdentifier.copy(), fullPath.copy()); } void OriginQuotaManager::removeDatabase(SecurityOrigin* origin, const String& databaseIdentifier) { ASSERT(m_usageRecordGuardLocked); - - if (OriginUsageRecord* usageRecord = m_usageMap.get(origin)) + + if (OriginUsageRecord* usageRecord = m_usageMap.get(origin)) usageRecord->removeDatabase(databaseIdentifier); } void OriginQuotaManager::removeOrigin(SecurityOrigin* origin) { ASSERT(m_usageRecordGuardLocked); - + if (OriginUsageRecord* usageRecord = m_usageMap.get(origin)) { m_usageMap.remove(origin); delete usageRecord; @@ -107,21 +107,20 @@ void OriginQuotaManager::markDatabase(Database* database) RefPtr<SecurityOrigin> origin = database->securityOriginCopy(); OriginUsageRecord* usageRecord = m_usageMap.get(origin); ASSERT(usageRecord); - + usageRecord->markDatabase(database->stringIdentifier()); } unsigned long long OriginQuotaManager::diskUsage(SecurityOrigin* origin) const { ASSERT(m_usageRecordGuardLocked); - + OriginUsageRecord* usageRecord = m_usageMap.get(origin); ASSERT(usageRecord); - + return usageRecord->diskUsage(); } - } #endif // ENABLE(DATABASE) diff --git a/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp b/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp index 5f4957f..684df53 100644 --- a/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp +++ b/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp @@ -44,10 +44,10 @@ void OriginUsageRecord::addDatabase(const String& identifier, const String& full ASSERT(!m_databaseMap.contains(identifier)); ASSERT_ARG(identifier, identifier.impl()->refCount() == 1); ASSERT_ARG(fullPath, fullPath.impl()->refCount() == 1); - + m_databaseMap.set(identifier, DatabaseEntry(fullPath)); m_unknownSet.add(identifier); - + m_cachedDiskUsageIsValid = false; } @@ -81,13 +81,13 @@ unsigned long long OriginUsageRecord::diskUsage() for (; iUnknown != endUnknown; ++iUnknown) { const String& path = m_databaseMap.get(*iUnknown).filename; ASSERT(!path.isEmpty()); - + // When we can't determine the file size, we'll just have to assume the file is missing/inaccessible. long long size = SQLiteFileSystem::getDatabaseFileSize(path); m_databaseMap.set(*iUnknown, DatabaseEntry(path, size)); } m_unknownSet.clear(); - + // Recalculate the cached usage value. m_cachedDiskUsage = 0; HashMap<String, DatabaseEntry>::iterator iDatabase = m_databaseMap.begin(); @@ -98,7 +98,7 @@ unsigned long long OriginUsageRecord::diskUsage() m_cachedDiskUsageIsValid = true; return m_cachedDiskUsage; } - + } #endif diff --git a/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.h b/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.h index 3442ae1..609a793 100644 --- a/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.h +++ b/src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.h @@ -68,4 +68,4 @@ private: #endif -#endif +#endif diff --git a/src/3rdparty/webkit/WebCore/storage/SQLError.h b/src/3rdparty/webkit/WebCore/storage/SQLError.h index b6ebb5c..a17efa9 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLError.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLError.h @@ -42,7 +42,7 @@ public: unsigned code() const { return m_code; } String message() const { return m_message.copy(); } - + private: SQLError(unsigned code, const String& message) : m_code(code), m_message(message.copy()) { } unsigned m_code; diff --git a/src/3rdparty/webkit/WebCore/storage/SQLResultSetRowList.h b/src/3rdparty/webkit/WebCore/storage/SQLResultSetRowList.h index 96a6aa1..92b5ec0 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLResultSetRowList.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLResultSetRowList.h @@ -39,7 +39,7 @@ namespace WebCore { class SQLResultSetRowList : public RefCounted<SQLResultSetRowList> { public: static PassRefPtr<SQLResultSetRowList> create() { return adoptRef(new SQLResultSetRowList); } - + const Vector<String>& columnNames() const { return m_columns; } const Vector<SQLValue>& values() const { return m_result; } @@ -50,7 +50,7 @@ public: private: SQLResultSetRowList() { } - + Vector<String> m_columns; Vector<SQLValue> m_result; }; diff --git a/src/3rdparty/webkit/WebCore/storage/SQLStatement.cpp b/src/3rdparty/webkit/WebCore/storage/SQLStatement.cpp index 38ca75d..970f757 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLStatement.cpp +++ b/src/3rdparty/webkit/WebCore/storage/SQLStatement.cpp @@ -57,24 +57,24 @@ SQLStatement::SQLStatement(const String& statement, const Vector<SQLValue>& argu , m_readOnly(readOnly) { } - + bool SQLStatement::execute(Database* db) { ASSERT(!m_resultSet); - + // If we're re-running this statement after a quota violation, we need to clear that error now clearFailureDueToQuota(); - // This transaction might have been marked bad while it was being set up on the main thread, + // This transaction might have been marked bad while it was being set up on the main thread, // so if there is still an error, return false. if (m_error) return false; - + if (m_readOnly) db->setAuthorizerReadOnly(); - + SQLiteDatabase* database = &db->m_sqliteDatabase; - + SQLiteStatement statement(*database, m_statement); int result = statement.prepare(); @@ -98,7 +98,7 @@ bool SQLStatement::execute(Database* db) setFailureDueToQuota(); return false; } - + if (result != SQLResultOk) { LOG(StorageAPI, "Failed to bind value index %i to statement for query '%s'", i + 1, m_statement.ascii().data()); m_error = SQLError::create(1, database->lastErrorMsg()); @@ -165,9 +165,9 @@ void SQLStatement::setVersionMismatchedError() bool SQLStatement::performCallback(SQLTransaction* transaction) { ASSERT(transaction); - + bool callbackError = false; - + // Call the appropriate statement callback and track if it resulted in an error, // because then we need to jump to the transaction error callback. if (m_error) { @@ -195,9 +195,9 @@ void SQLStatement::clearFailureDueToQuota() m_error = 0; } -bool SQLStatement::lastExecutionFailedDueToQuota() const -{ - return m_error && m_error->code() == 4; +bool SQLStatement::lastExecutionFailedDueToQuota() const +{ + return m_error && m_error->code() == 4; } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/SQLStatement.h b/src/3rdparty/webkit/WebCore/storage/SQLStatement.h index 831aecc..f01f7bf 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLStatement.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLStatement.h @@ -52,10 +52,10 @@ class String; class SQLStatement : public ThreadSafeShared<SQLStatement> { public: static PassRefPtr<SQLStatement> create(const String&, const Vector<SQLValue>&, PassRefPtr<SQLStatementCallback>, PassRefPtr<SQLStatementErrorCallback>, bool readOnly); - + bool execute(Database*); bool lastExecutionFailedDueToQuota() const; - + bool hasStatementCallback() const { return m_statementCallback; } bool hasStatementErrorCallback() const { return m_statementErrorCallback; } @@ -63,22 +63,22 @@ public: void setVersionMismatchedError(); bool performCallback(SQLTransaction*); - + SQLError* sqlError() const { return m_error.get(); } private: SQLStatement(const String& statement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> errorCallback, bool readOnly); void setFailureDueToQuota(); void clearFailureDueToQuota(); - + String m_statement; Vector<SQLValue> m_arguments; RefPtr<SQLStatementCallback> m_statementCallback; RefPtr<SQLStatementErrorCallback> m_statementErrorCallback; - + RefPtr<SQLError> m_error; RefPtr<SQLResultSet> m_resultSet; - + bool m_readOnly; }; diff --git a/src/3rdparty/webkit/WebCore/storage/SQLStatementCallback.h b/src/3rdparty/webkit/WebCore/storage/SQLStatementCallback.h index 14d19bb..31f5c0c 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLStatementCallback.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLStatementCallback.h @@ -36,7 +36,7 @@ namespace WebCore { class SQLTransaction; class SQLResultSet; - + class SQLStatementCallback : public ThreadSafeShared<SQLStatementCallback> { public: virtual ~SQLStatementCallback() { } diff --git a/src/3rdparty/webkit/WebCore/storage/SQLStatementErrorCallback.h b/src/3rdparty/webkit/WebCore/storage/SQLStatementErrorCallback.h index ef0c328..29127ce 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLStatementErrorCallback.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLStatementErrorCallback.h @@ -37,7 +37,7 @@ namespace WebCore { class SQLTransaction; class SQLError; - + class SQLStatementErrorCallback : public ThreadSafeShared<SQLStatementErrorCallback> { public: virtual ~SQLStatementErrorCallback() { } diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp index 3331e6e..28940a7 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp @@ -35,11 +35,9 @@ #include "Database.h" #include "DatabaseAuthorizer.h" #include "DatabaseDetails.h" -#include "DatabaseTracker.h" #include "Document.h" #include "ExceptionCode.h" #include "Logging.h" -#include "OriginQuotaManager.h" #include "Page.h" #include "PlatformString.h" #include "SecurityOrigin.h" @@ -50,24 +48,26 @@ #include "SQLStatement.h" #include "SQLStatementCallback.h" #include "SQLStatementErrorCallback.h" +#include "SQLTransactionClient.h" +#include "SQLTransactionCoordinator.h" #include "SQLValue.h" -// There's no way of knowing exactly how much more space will be required when a statement hits the quota limit. +// There's no way of knowing exactly how much more space will be required when a statement hits the quota limit. // For now, we'll arbitrarily choose currentQuota + 1mb. // In the future we decide to track if a size increase wasn't enough, and ask for larger-and-larger increases until its enough. static const int DefaultQuotaSizeIncrease = 1048576; namespace WebCore { -PassRefPtr<SQLTransaction> SQLTransaction::create(Database* db, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, - PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper> wrapper) +PassRefPtr<SQLTransaction> SQLTransaction::create(Database* db, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, + PassRefPtr<VoidCallback> successCallback, PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) { - return adoptRef(new SQLTransaction(db, callback, errorCallback, successCallback, wrapper)); + return adoptRef(new SQLTransaction(db, callback, errorCallback, successCallback, wrapper, readOnly)); } -SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback, - PassRefPtr<SQLTransactionWrapper> wrapper) - : m_nextStep(&SQLTransaction::openTransactionAndPreflight) +SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> callback, PassRefPtr<SQLTransactionErrorCallback> errorCallback, PassRefPtr<VoidCallback> successCallback, + PassRefPtr<SQLTransactionWrapper> wrapper, bool readOnly) + : m_nextStep(&SQLTransaction::acquireLock) , m_executeSqlAllowed(false) , m_database(db) , m_wrapper(wrapper) @@ -76,6 +76,8 @@ SQLTransaction::SQLTransaction(Database* db, PassRefPtr<SQLTransactionCallback> , m_errorCallback(errorCallback) , m_shouldRetryCurrentStatement(false) , m_modifiedDatabase(false) + , m_lockAcquired(false) + , m_readOnly(readOnly) { ASSERT(m_database); } @@ -91,11 +93,13 @@ void SQLTransaction::executeSQL(const String& sqlStatement, const Vector<SQLValu return; } - bool readOnlyMode = false; - Page* page = m_database->document()->page(); - if (!page || page->settings()->privateBrowsingEnabled()) - readOnlyMode = true; - + bool readOnlyMode = m_readOnly; + if (!readOnlyMode) { + Page* page = m_database->document()->page(); + if (!page || page->settings()->privateBrowsingEnabled()) + readOnlyMode = true; + } + RefPtr<SQLStatement> statement = SQLStatement::create(sqlStatement, arguments, callback, callbackError, readOnlyMode); if (m_database->deleted()) @@ -116,7 +120,9 @@ void SQLTransaction::enqueueStatement(PassRefPtr<SQLStatement> statement) #ifndef NDEBUG const char* SQLTransaction::debugStepName(SQLTransaction::TransactionStepMethod step) { - if (step == &SQLTransaction::openTransactionAndPreflight) + if (step == &SQLTransaction::acquireLock) + return "acquireLock"; + else if (step == &SQLTransaction::openTransactionAndPreflight) return "openTransactionAndPreflight"; else if (step == &SQLTransaction::runStatements) return "runStatements"; @@ -145,18 +151,21 @@ void SQLTransaction::checkAndHandleClosedDatabase() { if (!m_database->stopped()) return; - + // If the database was stopped, don't do anything and cancel queued work LOG(StorageAPI, "Database was stopped - cancelling work for this transaction"); MutexLocker locker(m_statementMutex); m_statementQueue.clear(); m_nextStep = 0; - + // The current SQLite transaction should be stopped, as well if (m_sqliteTransaction) { m_sqliteTransaction->stop(); m_sqliteTransaction.clear(); } + + if (m_lockAcquired) + m_database->transactionCoordinator()->releaseLock(this); } @@ -164,14 +173,15 @@ bool SQLTransaction::performNextStep() { LOG(StorageAPI, "Step %s\n", debugStepName(m_nextStep)); - ASSERT(m_nextStep == &SQLTransaction::openTransactionAndPreflight || + ASSERT(m_nextStep == &SQLTransaction::acquireLock || + m_nextStep == &SQLTransaction::openTransactionAndPreflight || m_nextStep == &SQLTransaction::runStatements || m_nextStep == &SQLTransaction::postflightAndCommit || m_nextStep == &SQLTransaction::cleanupAfterSuccessCallback || m_nextStep == &SQLTransaction::cleanupAfterTransactionErrorCallback); - + checkAndHandleClosedDatabase(); - + if (m_nextStep) (this->*m_nextStep)(); @@ -190,14 +200,28 @@ void SQLTransaction::performPendingCallback() m_nextStep == &SQLTransaction::deliverSuccessCallback); checkAndHandleClosedDatabase(); - + if (m_nextStep) (this->*m_nextStep)(); } +void SQLTransaction::acquireLock() +{ + m_database->transactionCoordinator()->acquireLock(this, m_readOnly); +} + +void SQLTransaction::lockAcquired() +{ + m_lockAcquired = true; + m_nextStep = &SQLTransaction::openTransactionAndPreflight; + LOG(StorageAPI, "Scheduling openTransactionAndPreflight immediately for transaction %p\n", this); + m_database->scheduleTransactionStep(this, true); +} + void SQLTransaction::openTransactionAndPreflight() { ASSERT(!m_database->m_sqliteDatabase.transactionInProgress()); + ASSERT(m_lockAcquired); LOG(StorageAPI, "Opening and preflighting transaction %p", this); @@ -210,14 +234,14 @@ void SQLTransaction::openTransactionAndPreflight() // Set the maximum usage for this transaction m_database->m_sqliteDatabase.setMaximumSize(m_database->maximumSize()); - + ASSERT(!m_sqliteTransaction); m_sqliteTransaction.set(new SQLiteTransaction(m_database->m_sqliteDatabase)); - + m_database->m_databaseAuthorizer->disable(); m_sqliteTransaction->begin(); - m_database->m_databaseAuthorizer->enable(); - + m_database->m_databaseAuthorizer->enable(); + // Transaction Steps 1+2 - Open a transaction to the database, jumping to the error callback if that fails if (!m_sqliteTransaction->inProgress()) { ASSERT(!m_database->m_sqliteDatabase.transactionInProgress()); @@ -226,7 +250,7 @@ void SQLTransaction::openTransactionAndPreflight() handleTransactionError(false); return; } - + // Transaction Steps 3 - Peform preflight steps, jumping to the error callback if they fail if (m_wrapper && !m_wrapper->performPreflight(this)) { ASSERT(!m_database->m_sqliteDatabase.transactionInProgress()); @@ -238,7 +262,7 @@ void SQLTransaction::openTransactionAndPreflight() handleTransactionError(false); return; } - + // Transaction Step 4 - Invoke the transaction callback with the new SQLTransaction object m_nextStep = &SQLTransaction::deliverTransactionCallback; LOG(StorageAPI, "Scheduling deliverTransactionCallback for transaction %p\n", this); @@ -273,6 +297,8 @@ void SQLTransaction::scheduleToRunStatements() void SQLTransaction::runStatements() { + ASSERT(m_lockAcquired); + // If there is a series of statements queued up that are all successful and have no associated // SQLStatementCallback objects, then we can burn through the queue do { @@ -280,7 +306,7 @@ void SQLTransaction::runStatements() m_shouldRetryCurrentStatement = false; // FIXME - Another place that needs fixing up after <rdar://problem/5628468> is addressed. // See ::openTransactionAndPreflight() for discussion - + // Reset the maximum size here, as it was increased to allow us to retry this statement m_database->m_sqliteDatabase.setMaximumSize(m_database->maximumSize()); } else { @@ -290,14 +316,14 @@ void SQLTransaction::runStatements() handleCurrentStatementError(); break; } - + // Otherwise, advance to the next statement getNextStatement(); } } while (runCurrentStatement()); - + // If runCurrentStatement() returned false, that means either there was no current statement to run, - // or the current statement requires a callback to complete. In the later case, it also scheduled + // or the current statement requires a callback to complete. In the later case, it also scheduled // the callback or performed any other additional work so we can return if (!m_currentStatement) postflightAndCommit(); @@ -306,7 +332,7 @@ void SQLTransaction::runStatements() void SQLTransaction::getNextStatement() { m_currentStatement = 0; - + MutexLocker locker(m_statementMutex); if (!m_statementQueue.isEmpty()) { m_currentStatement = m_statementQueue.first(); @@ -318,20 +344,17 @@ bool SQLTransaction::runCurrentStatement() { if (!m_currentStatement) return false; - + m_database->m_databaseAuthorizer->reset(); - + if (m_currentStatement->execute(m_database.get())) { if (m_database->m_databaseAuthorizer->lastActionChangedDatabase()) { // Flag this transaction as having changed the database for later delegate notification m_modifiedDatabase = true; // Also dirty the size of this database file for calculating quota usage - OriginQuotaManager& manager(DatabaseTracker::tracker().originQuotaManager()); - Locker<OriginQuotaManager> locker(manager); - - manager.markDatabase(m_database.get()); + m_database->transactionClient()->didExecuteStatement(this); } - + if (m_currentStatement->hasStatementCallback()) { m_nextStep = &SQLTransaction::deliverStatementCallback; LOG(StorageAPI, "Scheduling deliverStatementCallback for transaction %p\n", this); @@ -340,16 +363,16 @@ bool SQLTransaction::runCurrentStatement() } return true; } - + if (m_currentStatement->lastExecutionFailedDueToQuota()) { m_nextStep = &SQLTransaction::deliverQuotaIncreaseCallback; LOG(StorageAPI, "Scheduling deliverQuotaIncreaseCallback for transaction %p\n", this); m_database->scheduleTransactionCallback(this); return false; } - + handleCurrentStatementError(); - + return false; } @@ -372,7 +395,7 @@ void SQLTransaction::handleCurrentStatementError() void SQLTransaction::deliverStatementCallback() { ASSERT(m_currentStatement); - + // Transaction Step 6.6 and 6.3(error) - If the statement callback went wrong, jump to the transaction error callback // Otherwise, continue to loop through the statement queue m_executeSqlAllowed = true; @@ -390,27 +413,18 @@ void SQLTransaction::deliverQuotaIncreaseCallback() { ASSERT(m_currentStatement); ASSERT(!m_shouldRetryCurrentStatement); - - Page* page = m_database->document()->page(); - ASSERT(page); - - RefPtr<SecurityOrigin> origin = m_database->securityOriginCopy(); - - unsigned long long currentQuota = DatabaseTracker::tracker().quotaForOrigin(origin.get()); - page->chrome()->client()->exceededDatabaseQuota(m_database->document()->frame(), m_database->stringIdentifier()); - unsigned long long newQuota = DatabaseTracker::tracker().quotaForOrigin(origin.get()); - - // If the new quota ended up being larger than the old quota, we will retry the statement. - if (newQuota > currentQuota) - m_shouldRetryCurrentStatement = true; - + + m_shouldRetryCurrentStatement = m_database->transactionClient()->didExceedQuota(this); + m_nextStep = &SQLTransaction::runStatements; LOG(StorageAPI, "Scheduling runStatements for transaction %p\n", this); m_database->scheduleTransactionStep(this); } void SQLTransaction::postflightAndCommit() -{ +{ + ASSERT(m_lockAcquired); + // Transaction Step 7 - Peform postflight steps, jumping to the error callback if they fail if (m_wrapper && !m_wrapper->performPostflight(this)) { m_transactionError = m_wrapper->sqlError(); @@ -419,10 +433,10 @@ void SQLTransaction::postflightAndCommit() handleTransactionError(false); return; } - + // Transacton Step 8+9 - Commit the transaction, jumping to the error callback if that fails ASSERT(m_sqliteTransaction); - + m_database->m_databaseAuthorizer->disable(); m_sqliteTransaction->commit(); m_database->m_databaseAuthorizer->enable(); @@ -433,21 +447,21 @@ void SQLTransaction::postflightAndCommit() handleTransactionError(false); return; } - + // The commit was successful, notify the delegates if the transaction modified this database if (m_modifiedDatabase) - DatabaseTracker::tracker().scheduleNotifyDatabaseChanged(m_database->m_securityOrigin.get(), m_database->m_name); - + m_database->transactionClient()->didCommitTransaction(this); + // Now release our unneeded callbacks, to break reference cycles. m_callback = 0; m_errorCallback = 0; - + // Transaction Step 10 - Deliver success callback, if there is one if (m_successCallback) { m_nextStep = &SQLTransaction::deliverSuccessCallback; LOG(StorageAPI, "Scheduling deliverSuccessCallback for transaction %p\n", this); m_database->scheduleTransactionCallback(this); - } else + } else cleanupAfterSuccessCallback(); } @@ -456,7 +470,7 @@ void SQLTransaction::deliverSuccessCallback() // Transaction Step 10 - Deliver success callback ASSERT(m_successCallback); m_successCallback->handleEvent(); - + // Release the last callback to break reference cycle m_successCallback = 0; @@ -469,11 +483,16 @@ void SQLTransaction::deliverSuccessCallback() void SQLTransaction::cleanupAfterSuccessCallback() { + ASSERT(m_lockAcquired); + // Transaction Step 11 - End transaction steps // There is no next step LOG(StorageAPI, "Transaction %p is complete\n", this); ASSERT(!m_database->m_sqliteDatabase.transactionInProgress()); m_nextStep = 0; + + // Release the lock on this database + m_database->transactionCoordinator()->releaseLock(this); } void SQLTransaction::handleTransactionError(bool inCallback) @@ -488,7 +507,7 @@ void SQLTransaction::handleTransactionError(bool inCallback) } return; } - + // No error callback, so fast-forward to: // Transaction Step 12 - Rollback the transaction. if (inCallback) { @@ -503,7 +522,7 @@ void SQLTransaction::handleTransactionError(bool inCallback) void SQLTransaction::deliverTransactionErrorCallback() { ASSERT(m_transactionError); - + // Transaction Step 12 - If exists, invoke error callback with the last // error to have occurred in this transaction. if (m_errorCallback) @@ -516,22 +535,24 @@ void SQLTransaction::deliverTransactionErrorCallback() void SQLTransaction::cleanupAfterTransactionErrorCallback() { + ASSERT(m_lockAcquired); + m_database->m_databaseAuthorizer->disable(); if (m_sqliteTransaction) { // Transaction Step 12 - Rollback the transaction. m_sqliteTransaction->rollback(); - + ASSERT(!m_database->m_sqliteDatabase.transactionInProgress()); m_sqliteTransaction.clear(); } m_database->m_databaseAuthorizer->enable(); - + // Transaction Step 12 - Any still-pending statements in the transaction are discarded. { MutexLocker locker(m_statementMutex); m_statementQueue.clear(); } - + // Transaction is complete! There is no next step LOG(StorageAPI, "Transaction %p is complete with an error\n", this); ASSERT(!m_database->m_sqliteDatabase.transactionInProgress()); @@ -540,6 +561,9 @@ void SQLTransaction::cleanupAfterTransactionErrorCallback() // Now release our callbacks, to break reference cycles. m_callback = 0; m_errorCallback = 0; + + // Now release the lock on this database + m_database->transactionCoordinator()->releaseLock(this); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h index e77c183..0586cc5 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransaction.h @@ -60,34 +60,38 @@ public: virtual ~SQLTransactionWrapper() { } virtual bool performPreflight(SQLTransaction*) = 0; virtual bool performPostflight(SQLTransaction*) = 0; - + virtual SQLError* sqlError() const = 0; }; class SQLTransaction : public ThreadSafeShared<SQLTransaction> { public: - static PassRefPtr<SQLTransaction> create(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>); + static PassRefPtr<SQLTransaction> create(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, + PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly = false); ~SQLTransaction(); - - void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, + + void executeSQL(const String& sqlStatement, const Vector<SQLValue>& arguments, PassRefPtr<SQLStatementCallback> callback, PassRefPtr<SQLStatementErrorCallback> callbackError, ExceptionCode& e); - + + void lockAcquired(); bool performNextStep(); void performPendingCallback(); - + Database* database() { return m_database.get(); } private: - SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>); + SQLTransaction(Database*, PassRefPtr<SQLTransactionCallback>, PassRefPtr<SQLTransactionErrorCallback>, + PassRefPtr<VoidCallback>, PassRefPtr<SQLTransactionWrapper>, bool readOnly); typedef void (SQLTransaction::*TransactionStepMethod)(); TransactionStepMethod m_nextStep; - + void enqueueStatement(PassRefPtr<SQLStatement>); - + void checkAndHandleClosedDatabase(); - + + void acquireLock(); void openTransactionAndPreflight(); void deliverTransactionCallback(); void scheduleToRunStatements(); @@ -109,9 +113,9 @@ private: #endif RefPtr<SQLStatement> m_currentStatement; - + bool m_executeSqlAllowed; - + RefPtr<Database> m_database; RefPtr<SQLTransactionWrapper> m_wrapper; RefPtr<SQLTransactionCallback> m_callback; @@ -120,13 +124,15 @@ private: RefPtr<SQLError> m_transactionError; bool m_shouldRetryCurrentStatement; bool m_modifiedDatabase; - + bool m_lockAcquired; + bool m_readOnly; + Mutex m_statementMutex; Deque<RefPtr<SQLStatement> > m_statementQueue; OwnPtr<SQLiteTransaction> m_sqliteTransaction; }; - + } // namespace WebCore #endif diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCallback.h b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCallback.h index a4cd940..de3e85d 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCallback.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCallback.h @@ -37,7 +37,7 @@ namespace WebCore { class SQLTransaction; class SQLError; - + class SQLTransactionCallback : public ThreadSafeShared<SQLTransactionCallback> { public: virtual ~SQLTransactionCallback() { } diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.cpp b/src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.cpp new file mode 100644 index 0000000..e72f5ed --- /dev/null +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SQLTransactionClient.h" + +#include "ChromeClient.h" +#include "Database.h" +#include "DatabaseThread.h" +#include "DatabaseTracker.h" +#include "Document.h" +#include "OriginQuotaManager.h" +#include "Page.h" +#include "SQLTransaction.h" + +namespace WebCore { + +void SQLTransactionClient::didCommitTransaction(SQLTransaction* transaction) +{ + ASSERT(currentThread() == transaction->database()->document()->databaseThread()->getThreadID()); + Database* database = transaction->database(); + DatabaseTracker::tracker().scheduleNotifyDatabaseChanged( + database->document()->securityOrigin(), database->stringIdentifier()); +} + +void SQLTransactionClient::didExecuteStatement(SQLTransaction* transaction) +{ + ASSERT(currentThread() == transaction->database()->document()->databaseThread()->getThreadID()); + OriginQuotaManager& manager(DatabaseTracker::tracker().originQuotaManager()); + Locker<OriginQuotaManager> locker(manager); + manager.markDatabase(transaction->database()); +} + +bool SQLTransactionClient::didExceedQuota(SQLTransaction* transaction) +{ + ASSERT(isMainThread()); + Database* database = transaction->database(); + Page* page = database->document()->page(); + ASSERT(page); + + RefPtr<SecurityOrigin> origin = database->securityOriginCopy(); + + unsigned long long currentQuota = DatabaseTracker::tracker().quotaForOrigin(origin.get()); + page->chrome()->client()->exceededDatabaseQuota(database->document()->frame(), database->stringIdentifier()); + unsigned long long newQuota = DatabaseTracker::tracker().quotaForOrigin(origin.get()); + return (newQuota > currentQuota); +} + +} diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.h b/src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.h new file mode 100644 index 0000000..941c163 --- /dev/null +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLTransactionClient_h +#define SQLTransactionClient_h + +namespace WebCore { + + class SQLTransaction; + + // A client to the SQLTransaction class. Allows SQLTransaction to notify interested + // parties that certain things have happened in a transaction. + class SQLTransactionClient { + public: + void didCommitTransaction(SQLTransaction*); + void didExecuteStatement(SQLTransaction*); + bool didExceedQuota(SQLTransaction*); + }; +} + +#endif // SQLTransactionClient_h diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp new file mode 100644 index 0000000..a42734f --- /dev/null +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "SQLTransactionCoordinator.h" + +#include "CString.h" +#include "Database.h" +#include "SQLTransaction.h" +#include <wtf/Deque.h> +#include <wtf/HashMap.h> +#include <wtf/RefPtr.h> +#include <wtf/UnusedParam.h> + +namespace WebCore { + +static String getDatabaseIdentifier(SQLTransaction* transaction) +{ + Database* database = transaction->database(); + ASSERT(database); + return database->stringIdentifier(); +} + +void SQLTransactionCoordinator::acquireLock(SQLTransaction* transaction, bool readOnly) +{ + UNUSED_PARAM(readOnly); + + String dbIdentifier = getDatabaseIdentifier(transaction); + + TransactionsHashMap::iterator it = m_pendingTransactions.find(dbIdentifier); + if (it == m_pendingTransactions.end()) { + // No pending transactions for this DB + TransactionsQueue pendingTransactions; + pendingTransactions.append(transaction); + m_pendingTransactions.add(dbIdentifier, pendingTransactions); + + // Start the transaction + transaction->lockAcquired(); + } else { + // Another transaction is running on this DB; put this one in the queue + TransactionsQueue& pendingTransactions = it->second; + pendingTransactions.append(transaction); + } +} + +void SQLTransactionCoordinator::releaseLock(SQLTransaction* transaction) +{ + if (m_pendingTransactions.isEmpty()) + return; + + String dbIdentifier = getDatabaseIdentifier(transaction); + + TransactionsHashMap::iterator it = m_pendingTransactions.find(dbIdentifier); + ASSERT(it != m_pendingTransactions.end()); + TransactionsQueue& pendingTransactions = it->second; + ASSERT(!pendingTransactions.isEmpty()); + + // 'transaction' should always be the first transaction in this queue + ASSERT(pendingTransactions.first().get() == transaction); + + // Remove 'transaction' from the queue of pending transactions + pendingTransactions.removeFirst(); + if (pendingTransactions.isEmpty()) { + // No more pending transactions; delete dbIdentifier's queue + m_pendingTransactions.remove(it); + } else { + // We have more pending transactions; start the next one + pendingTransactions.first()->lockAcquired(); + } +} + +void SQLTransactionCoordinator::shutdown() +{ + // Clean up all pending transactions for all databases + m_pendingTransactions.clear(); +} + +} diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h new file mode 100644 index 0000000..08985cf --- /dev/null +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SQLTransactionCoordinator_h +#define SQLTransactionCoordinator_h + +#include "CString.h" +#include "StringHash.h" +#include <wtf/Deque.h> +#include <wtf/HashMap.h> +#include <wtf/RefPtr.h> + +namespace WebCore { + + class SQLTransaction; + + class SQLTransactionCoordinator { + public: + void acquireLock(SQLTransaction*, bool readOnly); + void releaseLock(SQLTransaction*); + void shutdown(); + private: + typedef Deque<RefPtr<SQLTransaction> > TransactionsQueue; + typedef HashMap<String, TransactionsQueue> TransactionsHashMap; + TransactionsHashMap m_pendingTransactions; + }; +} + +#endif // SQLTransactionCoordinator_h diff --git a/src/3rdparty/webkit/WebCore/storage/SQLTransactionErrorCallback.h b/src/3rdparty/webkit/WebCore/storage/SQLTransactionErrorCallback.h index 9dd3fd3..de99212 100644 --- a/src/3rdparty/webkit/WebCore/storage/SQLTransactionErrorCallback.h +++ b/src/3rdparty/webkit/WebCore/storage/SQLTransactionErrorCallback.h @@ -34,19 +34,17 @@ #include <wtf/Threading.h> namespace WebCore { - + class SQLError; - + class SQLTransactionErrorCallback : public ThreadSafeShared<SQLTransactionErrorCallback> { public: virtual ~SQLTransactionErrorCallback() { } virtual void handleEvent(SQLError*) = 0; }; - + } #endif #endif // SQLTransactionErrorCallback_h - - diff --git a/src/3rdparty/webkit/WebCore/storage/Storage.cpp b/src/3rdparty/webkit/WebCore/storage/Storage.cpp index 0166098..0a8eed7 100644 --- a/src/3rdparty/webkit/WebCore/storage/Storage.cpp +++ b/src/3rdparty/webkit/WebCore/storage/Storage.cpp @@ -20,9 +20,9 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #include "config.h" #include "Storage.h" @@ -59,13 +59,12 @@ unsigned Storage::length() const return m_storageArea->length(); } -String Storage::key(unsigned index, ExceptionCode& ec) const +String Storage::key(unsigned index) const { - ec = 0; if (!m_frame) return String(); - return m_storageArea->key(index, ec); + return m_storageArea->key(index); } String Storage::getItem(const String& key) const @@ -112,4 +111,3 @@ bool Storage::contains(const String& key) const } #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/Storage.h b/src/3rdparty/webkit/WebCore/storage/Storage.h index 77c5720..06cc97b 100644 --- a/src/3rdparty/webkit/WebCore/storage/Storage.h +++ b/src/3rdparty/webkit/WebCore/storage/Storage.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef Storage_h @@ -45,7 +45,7 @@ namespace WebCore { ~Storage(); unsigned length() const; - String key(unsigned index, ExceptionCode&) const; + String key(unsigned index) const; String getItem(const String&) const; void setItem(const String& key, const String& value, ExceptionCode&); void removeItem(const String&); @@ -53,11 +53,12 @@ namespace WebCore { bool contains(const String& key) const; + Frame* frame() { return m_frame; } void disconnectFrame() { m_frame = 0; } private: Storage(Frame*, PassRefPtr<StorageArea>); - + Frame* m_frame; RefPtr<StorageArea> m_storageArea; }; diff --git a/src/3rdparty/webkit/WebCore/storage/Storage.idl b/src/3rdparty/webkit/WebCore/storage/Storage.idl index 00c89ec..7127efd 100644 --- a/src/3rdparty/webkit/WebCore/storage/Storage.idl +++ b/src/3rdparty/webkit/WebCore/storage/Storage.idl @@ -34,8 +34,7 @@ module storage { Conditional=DOM_STORAGE ] Storage { readonly attribute [DontEnum] unsigned long length; - [DontEnum] DOMString key(in unsigned long index) - raises(DOMException); + [DontEnum, ConvertNullStringTo=Null] DOMString key(in unsigned long index); [DontEnum, ConvertNullStringTo=Null] DOMString getItem(in DOMString key); [DontEnum] void setItem(in DOMString key, in DOMString data) raises(DOMException); diff --git a/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp b/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp deleted file mode 100644 index e69de29..0000000 --- a/src/3rdparty/webkit/WebCore/storage/StorageArea.cpp +++ /dev/null diff --git a/src/3rdparty/webkit/WebCore/storage/StorageArea.h b/src/3rdparty/webkit/WebCore/storage/StorageArea.h index 6ae10c1..e0f7f06 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageArea.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageArea.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef StorageArea_h @@ -48,7 +48,7 @@ namespace WebCore { // The HTML5 DOM Storage API virtual unsigned length() const = 0; - virtual String key(unsigned index, ExceptionCode& ec) const = 0; + virtual String key(unsigned index) const = 0; virtual String getItem(const String& key) const = 0; virtual void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame) = 0; virtual void removeItem(const String& key, Frame* sourceFrame) = 0; diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp index 9eb59e3..0d69216 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp +++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp @@ -20,9 +20,9 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - + #include "config.h" #include "StorageAreaImpl.h" @@ -47,7 +47,7 @@ StorageAreaImpl::~StorageAreaImpl() { } -StorageAreaImpl::StorageAreaImpl(StorageType storageType, SecurityOrigin* origin, PassRefPtr<StorageSyncManager> syncManager) +StorageAreaImpl::StorageAreaImpl(StorageType storageType, PassRefPtr<SecurityOrigin> origin, PassRefPtr<StorageSyncManager> syncManager) : m_storageType(storageType) , m_securityOrigin(origin) , m_storageMap(StorageMap::create()) @@ -67,15 +67,15 @@ StorageAreaImpl::StorageAreaImpl(StorageType storageType, SecurityOrigin* origin } } -PassRefPtr<StorageAreaImpl> StorageAreaImpl::copy(SecurityOrigin* origin) +PassRefPtr<StorageAreaImpl> StorageAreaImpl::copy() { ASSERT(!m_isShutdown); - return adoptRef(new StorageAreaImpl(origin, this)); + return adoptRef(new StorageAreaImpl(this)); } -StorageAreaImpl::StorageAreaImpl(SecurityOrigin* origin, StorageAreaImpl* area) +StorageAreaImpl::StorageAreaImpl(StorageAreaImpl* area) : m_storageType(area->m_storageType) - , m_securityOrigin(origin) + , m_securityOrigin(area->m_securityOrigin) , m_storageMap(area->m_storageMap) , m_storageSyncManager(area->m_storageSyncManager) #ifndef NDEBUG @@ -87,32 +87,37 @@ StorageAreaImpl::StorageAreaImpl(SecurityOrigin* origin, StorageAreaImpl* area) ASSERT(!m_isShutdown); } +static bool privateBrowsingEnabled(Frame* frame) +{ +#if PLATFORM(CHROMIUM) + // The frame pointer can be NULL in Chromium since this call is made in a different + // process from where the Frame object exists. Luckily, private browseing is + // implemented differently in Chromium, so it'd never return true anyway. + ASSERT(!frame); + return false; +#else + return frame->page()->settings()->privateBrowsingEnabled(); +#endif +} + unsigned StorageAreaImpl::length() const { ASSERT(!m_isShutdown); return m_storageMap->length(); } -String StorageAreaImpl::key(unsigned index, ExceptionCode& ec) const +String StorageAreaImpl::key(unsigned index) const { ASSERT(!m_isShutdown); blockUntilImportComplete(); - - String key; - - if (!m_storageMap->key(index, key)) { - ec = INDEX_SIZE_ERR; - return String(); - } - - return key; + return m_storageMap->key(index); } String StorageAreaImpl::getItem(const String& key) const { ASSERT(!m_isShutdown); blockUntilImportComplete(); - + return m_storageMap->getItem(key); } @@ -121,8 +126,8 @@ void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionC ASSERT(!m_isShutdown); ASSERT(!value.isNull()); blockUntilImportComplete(); - - if (frame->page()->settings()->privateBrowsingEnabled()) { + + if (privateBrowsingEnabled(frame)) { ec = QUOTA_EXCEEDED_ERR; return; } @@ -133,10 +138,10 @@ void StorageAreaImpl::setItem(const String& key, const String& value, ExceptionC // ec = QUOTA_EXCEEDED_ERR; // return; // } - - String oldValue; + + String oldValue; RefPtr<StorageMap> newMap = m_storageMap->setItem(key, value, oldValue); - + if (newMap) m_storageMap = newMap.release(); @@ -152,8 +157,8 @@ void StorageAreaImpl::removeItem(const String& key, Frame* frame) { ASSERT(!m_isShutdown); blockUntilImportComplete(); - - if (frame->page()->settings()->privateBrowsingEnabled()) + + if (privateBrowsingEnabled(frame)) return; String oldValue; @@ -173,12 +178,12 @@ void StorageAreaImpl::clear(Frame* frame) { ASSERT(!m_isShutdown); blockUntilImportComplete(); - - if (frame->page()->settings()->privateBrowsingEnabled()) + + if (privateBrowsingEnabled(frame)) return; - + m_storageMap = StorageMap::create(); - + if (m_storageAreaSync) m_storageAreaSync->scheduleClear(); dispatchStorageEvent(String(), String(), String(), frame); @@ -188,7 +193,7 @@ bool StorageAreaImpl::contains(const String& key) const { ASSERT(!m_isShutdown); blockUntilImportComplete(); - + return m_storageMap->contains(key); } @@ -221,22 +226,25 @@ void StorageAreaImpl::blockUntilImportComplete() const void StorageAreaImpl::dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame) { - // We need to copy all relevant frames from every page to a vector since sending the event to one frame might mutate the frame tree - // of any given page in the group or mutate the page group itself. - Vector<RefPtr<Frame> > frames; +#if PLATFORM(CHROMIUM) + // FIXME: Events are currently broken in Chromium. + return; +#endif - // FIXME: When can this occur? Page* page = sourceFrame->page(); if (!page) return; + // We need to copy all relevant frames from every page to a vector since sending the event to one frame might mutate the frame tree + // of any given page in the group or mutate the page group itself. + Vector<RefPtr<Frame> > frames; if (m_storageType == SessionStorage) { // Send events only to our page. for (Frame* frame = page->mainFrame(); frame; frame = frame->tree()->traverseNext()) { if (frame->document()->securityOrigin()->equal(securityOrigin())) frames.append(frame); } - + for (unsigned i = 0; i < frames.size(); ++i) frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->sessionStorage())); } else { @@ -249,13 +257,12 @@ void StorageAreaImpl::dispatchStorageEvent(const String& key, const String& oldV frames.append(frame); } } - + for (unsigned i = 0; i < frames.size(); ++i) frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->documentURI(), sourceFrame->domWindow(), frames[i]->domWindow()->localStorage())); - } + } } } #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h index d3f0785..b98482b 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef StorageAreaImpl_h @@ -40,19 +40,19 @@ namespace WebCore { class StorageAreaImpl : public StorageArea { public: - StorageAreaImpl(StorageType, SecurityOrigin*, PassRefPtr<StorageSyncManager>); + StorageAreaImpl(StorageType, PassRefPtr<SecurityOrigin>, PassRefPtr<StorageSyncManager>); virtual ~StorageAreaImpl(); // The HTML5 DOM Storage API (and contains) virtual unsigned length() const; - virtual String key(unsigned index, ExceptionCode& ec) const; + virtual String key(unsigned index) const; virtual String getItem(const String& key) const; virtual void setItem(const String& key, const String& value, ExceptionCode& ec, Frame* sourceFrame); virtual void removeItem(const String& key, Frame* sourceFrame); virtual void clear(Frame* sourceFrame); virtual bool contains(const String& key) const; - PassRefPtr<StorageAreaImpl> copy(SecurityOrigin*); + PassRefPtr<StorageAreaImpl> copy(); void close(); // Could be called from a background thread. @@ -60,7 +60,7 @@ namespace WebCore { SecurityOrigin* securityOrigin(); private: - StorageAreaImpl(SecurityOrigin*, StorageAreaImpl*); + StorageAreaImpl(StorageAreaImpl*); void blockUntilImportComplete() const; diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.cpp b/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.cpp index 01d2a65..2a642b4 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.cpp +++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -76,7 +76,7 @@ void StorageAreaSync::scheduleFinalSync() ASSERT(isMainThread()); // FIXME: We do this to avoid races, but it'd be better to make things safe without blocking. blockUntilImportComplete(); - + if (m_syncTimer.isActive()) m_syncTimer.stop(); else { @@ -127,7 +127,7 @@ void StorageAreaSync::syncTimerFired(Timer<StorageAreaSync>*) HashMap<String, String>::iterator it = m_changedItems.begin(); HashMap<String, String>::iterator end = m_changedItems.end(); - + { MutexLocker locker(m_syncLock); @@ -182,14 +182,14 @@ void StorageAreaSync::performImport() markImported(); return; } - + SQLiteStatement query(m_database, "SELECT key, value FROM ItemTable"); if (query.prepare() != SQLResultOk) { LOG_ERROR("Unable to select items from ItemTable for local storage"); markImported(); return; } - + HashMap<String, String> itemMap; int result = query.step(); @@ -205,13 +205,13 @@ void StorageAreaSync::performImport() } MutexLocker locker(m_importLock); - + HashMap<String, String>::iterator it = itemMap.begin(); HashMap<String, String>::iterator end = itemMap.end(); - + for (; it != end; ++it) m_storageArea->importItem(it->first, it->second); - + // Break the (ref count) cycle. m_storageArea = 0; m_importComplete = true; @@ -265,7 +265,7 @@ void StorageAreaSync::sync(bool clearItems, const HashMap<String, String>& items LOG_ERROR("Failed to prepare clear statement - cannot write to local storage database"); return; } - + int result = clear.step(); if (result != SQLResultDone) { LOG_ERROR("Failed to clear all items in the local storage database - %i", result); @@ -289,11 +289,11 @@ void StorageAreaSync::sync(bool clearItems, const HashMap<String, String>& items for (HashMap<String, String>::const_iterator it = items.begin(); it != end; ++it) { // Based on the null-ness of the second argument, decide whether this is an insert or a delete. - SQLiteStatement& query = it->second.isNull() ? remove : insert; + SQLiteStatement& query = it->second.isNull() ? remove : insert; query.bindText(1, it->first); - // If the second argument is non-null, we're doing an insert, so bind it as the value. + // If the second argument is non-null, we're doing an insert, so bind it as the value. if (!it->second.isNull()) query.bindText(2, it->second); @@ -335,4 +335,3 @@ void StorageAreaSync::performSync() } // namespace WebCore #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h b/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h index e436bef..9d6436f 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef StorageAreaSync_h @@ -39,7 +39,7 @@ namespace WebCore { class Frame; class StorageAreaImpl; class StorageSyncManager; - + class StorageAreaSync : public RefCounted<StorageAreaSync> { public: static PassRefPtr<StorageAreaSync> create(PassRefPtr<StorageSyncManager> storageSyncManager, PassRefPtr<StorageAreaImpl> storageArea); @@ -50,16 +50,16 @@ namespace WebCore { void scheduleItemForSync(const String& key, const String& value); void scheduleClear(); - + private: StorageAreaSync(PassRefPtr<StorageSyncManager> storageSyncManager, PassRefPtr<StorageAreaImpl> storageArea); void dispatchStorageEvent(const String& key, const String& oldValue, const String& newValue, Frame* sourceFrame); - Timer<StorageAreaSync> m_syncTimer; + Timer<StorageAreaSync> m_syncTimer; HashMap<String, String> m_changedItems; bool m_itemsCleared; - + bool m_finalSyncScheduled; RefPtr<StorageAreaImpl> m_storageArea; diff --git a/src/3rdparty/webkit/WebCore/storage/StorageEvent.cpp b/src/3rdparty/webkit/WebCore/storage/StorageEvent.cpp index 2e620d5..f3b3b70 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageEvent.cpp +++ b/src/3rdparty/webkit/WebCore/storage/StorageEvent.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -76,4 +76,3 @@ void StorageEvent::initStorageEvent(const AtomicString& type, bool canBubble, bo } // namespace WebCore #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/StorageEvent.h b/src/3rdparty/webkit/WebCore/storage/StorageEvent.h index 703fb5a..7e2bcff 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageEvent.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageEvent.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef StorageEvent_h @@ -55,16 +55,16 @@ namespace WebCore { virtual bool isStorageEvent() const { return true; } - private: + private: StorageEvent(); StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& uri, PassRefPtr<DOMWindow> source, Storage* storageArea); - + String m_key; String m_oldValue; String m_newValue; String m_uri; RefPtr<DOMWindow> m_source; - RefPtr<Storage> m_storageArea; + RefPtr<Storage> m_storageArea; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/StorageMap.cpp b/src/3rdparty/webkit/WebCore/storage/StorageMap.cpp index 4c350c8..6ddf323 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageMap.cpp +++ b/src/3rdparty/webkit/WebCore/storage/StorageMap.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -34,7 +34,7 @@ PassRefPtr<StorageMap> StorageMap::create() { return adoptRef(new StorageMap); } - + StorageMap::StorageMap() : m_iterator(m_map.end()) , m_iteratorIndex(UINT_MAX) @@ -57,19 +57,19 @@ void StorageMap::invalidateIterator() void StorageMap::setIteratorToIndex(unsigned index) const { // FIXME: Once we have bidirectional iterators for HashMap we can be more intelligent about this. - // The requested index will be closest to begin(), our current iterator, or end(), and we + // The requested index will be closest to begin(), our current iterator, or end(), and we // can take the shortest route. // Until that mechanism is available, we'll always increment our iterator from begin() or current. - + if (m_iteratorIndex == index) return; - + if (index < m_iteratorIndex) { m_iteratorIndex = 0; m_iterator = m_map.begin(); ASSERT(m_iterator != m_map.end()); } - + while (m_iteratorIndex < index) { ++m_iteratorIndex; ++m_iterator; @@ -82,15 +82,13 @@ unsigned StorageMap::length() const return m_map.size(); } -bool StorageMap::key(unsigned index, String& key) const +String StorageMap::key(unsigned index) const { if (index >= length()) - return false; - + return String(); + setIteratorToIndex(index); - - key = m_iterator->first; - return true; + return m_iterator->first; } String StorageMap::getItem(const String& key) const @@ -101,7 +99,7 @@ String StorageMap::getItem(const String& key) const PassRefPtr<StorageMap> StorageMap::setItem(const String& key, const String& value, String& oldValue) { ASSERT(!value.isNull()); - + // Implement copy-on-write semantics here. We're guaranteed that the only refs of StorageMaps belong to Storage objects // so if more than one Storage object refs this map, copy it before mutating it. if (refCount() > 1) { @@ -160,4 +158,3 @@ void StorageMap::importItem(const String& key, const String& value) const } #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/StorageMap.h b/src/3rdparty/webkit/WebCore/storage/StorageMap.h index c6f3bc9..afb90bb 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageMap.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageMap.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef StorageMap_h @@ -42,7 +42,7 @@ namespace WebCore { static PassRefPtr<StorageMap> create(); unsigned length() const; - bool key(unsigned index, String& key) const; + String key(unsigned index) const; String getItem(const String&) const; PassRefPtr<StorageMap> setItem(const String& key, const String& value, String& oldValue); PassRefPtr<StorageMap> removeItem(const String&, String& oldValue); diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h b/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h index edbe339..825581f 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespace.h @@ -48,6 +48,7 @@ namespace WebCore { virtual PassRefPtr<StorageArea> storageArea(SecurityOrigin*) = 0; virtual PassRefPtr<StorageNamespace> copy() = 0; virtual void close() = 0; + virtual void unlock() = 0; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp index 8b08a27..5ac22cf 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp +++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp @@ -64,11 +64,9 @@ PassRefPtr<StorageNamespace> StorageNamespaceImpl::sessionStorageNamespace() StorageNamespaceImpl::StorageNamespaceImpl(StorageType storageType, const String& path) : m_storageType(storageType) - , m_path(path.copy()) // FIXME: Is the .copy necessary? + , m_path(path.copy()) // Copy makes it safe for our other thread to access the path. , m_syncManager(0) -#ifndef NDEBUG , m_isShutdown(false) -#endif { if (m_storageType == LocalStorage && !m_path.isEmpty()) m_syncManager = StorageSyncManager::create(m_path); @@ -82,21 +80,22 @@ StorageNamespaceImpl::~StorageNamespaceImpl() ASSERT(localStorageNamespaceMap().get(m_path) == this); localStorageNamespaceMap().remove(m_path); } + + if (!m_isShutdown) + close(); } PassRefPtr<StorageNamespace> StorageNamespaceImpl::copy() { ASSERT(isMainThread()); ASSERT(!m_isShutdown); + ASSERT(m_storageType == SessionStorage); StorageNamespaceImpl* newNamespace = new StorageNamespaceImpl(m_storageType, m_path); StorageAreaMap::iterator end = m_storageAreaMap.end(); - for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) { - RefPtr<StorageAreaImpl> areaCopy = i->second->copy(i->first.get()); - newNamespace->m_storageAreaMap.set(i->first, areaCopy.release()); - } - + for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) + newNamespace->m_storageAreaMap.set(i->first, i->second->copy()); return adoptRef(newNamespace); } @@ -109,7 +108,7 @@ PassRefPtr<StorageArea> StorageNamespaceImpl::storageArea(SecurityOrigin* origin if (storageArea = m_storageAreaMap.get(origin)) return storageArea.release(); - storageArea = new StorageAreaImpl(m_storageType, origin, m_syncManager); + storageArea = adoptRef(new StorageAreaImpl(m_storageType, origin, m_syncManager)); m_storageAreaMap.set(origin, storageArea); return storageArea.release(); } @@ -119,13 +118,25 @@ void StorageNamespaceImpl::close() ASSERT(isMainThread()); ASSERT(!m_isShutdown); + // If we're session storage, we shouldn't need to do any work here. + if (m_storageType == SessionStorage) { + ASSERT(!m_syncManager); + return; + } + StorageAreaMap::iterator end = m_storageAreaMap.end(); for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it) it->second->close(); -#ifndef NDEBUG + if (m_syncManager) + m_syncManager->close(); + m_isShutdown = true; -#endif +} + +void StorageNamespaceImpl::unlock() +{ + // Because there's a single event loop per-process, this is a no-op. } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h index 4ec2f72..d3ef37f 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h @@ -49,6 +49,7 @@ namespace WebCore { virtual PassRefPtr<StorageArea> storageArea(SecurityOrigin*); virtual PassRefPtr<StorageNamespace> copy(); virtual void close(); + virtual void unlock(); private: StorageNamespaceImpl(StorageType, const String& path); @@ -62,9 +63,7 @@ namespace WebCore { String m_path; RefPtr<StorageSyncManager> m_syncManager; -#ifndef NDEBUG bool m_isShutdown; -#endif }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.cpp b/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.cpp index a935242..961b9b2 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.cpp +++ b/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.cpp @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" @@ -101,4 +101,3 @@ void StorageSyncManager::scheduleSync(PassRefPtr<StorageAreaSync> area) } // namespace WebCore #endif // ENABLE(DOM_STORAGE) - diff --git a/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.h b/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.h index 4c5e821..b8c817f 100644 --- a/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.h +++ b/src/3rdparty/webkit/WebCore/storage/StorageSyncManager.h @@ -20,7 +20,7 @@ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef StorageSyncManager_h |