summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/storage
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/storage')
-rw-r--r--src/3rdparty/webkit/WebCore/storage/ChangeVersionWrapper.cpp12
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Database.cpp65
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Database.h24
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Database.idl1
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.cpp67
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseAuthorizer.h10
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseDetails.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseThread.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseThread.h9
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseTracker.cpp78
-rw-r--r--src/3rdparty/webkit/WebCore/storage/DatabaseTracker.h16
-rw-r--r--src/3rdparty/webkit/WebCore/storage/LocalStorageTask.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/LocalStorageTask.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/LocalStorageThread.cpp11
-rw-r--r--src/3rdparty/webkit/WebCore/storage/LocalStorageThread.h4
-rw-r--r--src/3rdparty/webkit/WebCore/storage/OriginQuotaManager.cpp17
-rw-r--r--src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.cpp10
-rw-r--r--src/3rdparty/webkit/WebCore/storage/OriginUsageRecord.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLError.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLResultSetRowList.h4
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLStatement.cpp24
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLStatement.h12
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLStatementCallback.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLStatementErrorCallback.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransaction.cpp166
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransaction.h34
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransactionCallback.h2
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.cpp76
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransactionClient.h48
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.cpp105
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransactionCoordinator.h56
-rw-r--r--src/3rdparty/webkit/WebCore/storage/SQLTransactionErrorCallback.h8
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Storage.cpp10
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Storage.h7
-rw-r--r--src/3rdparty/webkit/WebCore/storage/Storage.idl3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageArea.cpp0
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageArea.h4
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.cpp83
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaImpl.h10
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaSync.cpp23
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageAreaSync.h10
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageEvent.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageEvent.h8
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageMap.cpp25
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageMap.h4
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespace.h1
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.cpp33
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageNamespaceImpl.h3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageSyncManager.cpp3
-rw-r--r--src/3rdparty/webkit/WebCore/storage/StorageSyncManager.h2
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