Modified: trunk/Source/WebCore/ChangeLog (158057 => 158058)
--- trunk/Source/WebCore/ChangeLog 2013-10-25 22:01:35 UTC (rev 158057)
+++ trunk/Source/WebCore/ChangeLog 2013-10-25 22:03:40 UTC (rev 158058)
@@ -1,3 +1,26 @@
+2013-10-25 Mark Lam <[email protected]>
+
+ DatabaseManager's ProposedDatabases need to be thread-safe.
+ https://bugs.webkit.org/show_bug.cgi?id=123313.
+
+ Reviewed by Geoffrey Garen.
+
+ No new tests.
+
+ * Modules/webdatabase/DatabaseManager.cpp:
+ (WebCore::DatabaseManager::DatabaseManager):
+ (WebCore::DatabaseManager::existingDatabaseContextFor):
+ (WebCore::DatabaseManager::registerDatabaseContext):
+ (WebCore::DatabaseManager::unregisterDatabaseContext):
+ (WebCore::DatabaseManager::didConstructDatabaseContext):
+ (WebCore::DatabaseManager::didDestructDatabaseContext):
+ (WebCore::DatabaseManager::openDatabaseBackend):
+ (WebCore::DatabaseManager::addProposedDatabase):
+ (WebCore::DatabaseManager::removeProposedDatabase):
+ (WebCore::DatabaseManager::fullPathForDatabase):
+ (WebCore::DatabaseManager::detailsForNameAndOrigin):
+ * Modules/webdatabase/DatabaseManager.h:
+
2013-10-25 Joseph Pecoraro <[email protected]>
Upstream ENABLE(REMOTE_INSPECTOR) and enable on iOS and Mac
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp (158057 => 158058)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp 2013-10-25 22:01:35 UTC (rev 158057)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.cpp 2013-10-25 22:03:40 UTC (rev 158058)
@@ -55,13 +55,12 @@
, m_origin(origin->isolatedCopy())
, m_details(name.isolatedCopy(), displayName.isolatedCopy(), estimatedSize, 0)
{
- ASSERT(!m_manager.m_proposedDatabase);
- m_manager.m_proposedDatabase = this;
+ m_manager.addProposedDatabase(this);
}
DatabaseManager::ProposedDatabase::~ProposedDatabase()
{
- m_manager.m_proposedDatabase = 0;
+ m_manager.removeProposedDatabase(this);
}
DatabaseManager& DatabaseManager::manager()
@@ -83,7 +82,6 @@
, m_databaseContextRegisteredCount(0)
, m_databaseContextInstanceCount(0)
#endif
- , m_proposedDatabase(0)
{
ASSERT(m_server); // We should always have a server to work with.
}
@@ -144,7 +142,7 @@
PassRefPtr<DatabaseContext> DatabaseManager::existingDatabaseContextFor(ScriptExecutionContext* context)
{
- MutexLocker locker(m_contextMapLock);
+ MutexLocker locker(m_lock);
ASSERT(m_databaseContextRegisteredCount >= 0);
ASSERT(m_databaseContextInstanceCount >= 0);
@@ -175,7 +173,7 @@
void DatabaseManager::registerDatabaseContext(DatabaseContext* databaseContext)
{
- MutexLocker locker(m_contextMapLock);
+ MutexLocker locker(m_lock);
ScriptExecutionContext* context = databaseContext->scriptExecutionContext();
m_contextMap.set(context, databaseContext);
#if !ASSERT_DISABLED
@@ -185,7 +183,7 @@
void DatabaseManager::unregisterDatabaseContext(DatabaseContext* databaseContext)
{
- MutexLocker locker(m_contextMapLock);
+ MutexLocker locker(m_lock);
ScriptExecutionContext* context = databaseContext->scriptExecutionContext();
ASSERT(m_contextMap.get(context));
#if !ASSERT_DISABLED
@@ -197,13 +195,13 @@
#if !ASSERT_DISABLED
void DatabaseManager::didConstructDatabaseContext()
{
- MutexLocker lock(m_contextMapLock);
+ MutexLocker lock(m_lock);
m_databaseContextInstanceCount++;
}
void DatabaseManager::didDestructDatabaseContext()
{
- MutexLocker lock(m_contextMapLock);
+ MutexLocker lock(m_lock);
m_databaseContextInstanceCount--;
ASSERT(m_databaseContextRegisteredCount <= m_databaseContextInstanceCount);
}
@@ -296,6 +294,18 @@
return backend.release();
}
+void DatabaseManager::addProposedDatabase(ProposedDatabase* proposedDb)
+{
+ MutexLocker locker(m_lock);
+ m_proposedDatabases.add(proposedDb);
+}
+
+void DatabaseManager::removeProposedDatabase(ProposedDatabase* proposedDb)
+{
+ MutexLocker locker(m_lock);
+ m_proposedDatabases.remove(proposedDb);
+}
+
PassRefPtr<Database> DatabaseManager::openDatabase(ScriptExecutionContext* context,
const String& name, const String& expectedVersion, const String& displayName,
unsigned long estimatedSize, PassRefPtr<DatabaseCallback> creationCallback,
@@ -369,9 +379,12 @@
String DatabaseManager::fullPathForDatabase(SecurityOrigin* origin, const String& name, bool createIfDoesNotExist)
{
- ProposedDatabase* db = m_proposedDatabase;
- if (db && db->details().name() == name && db->origin()->equal(origin))
- return String();
+ {
+ MutexLocker locker(m_lock);
+ for (HashSet<ProposedDatabase*>::iterator iter = m_proposedDatabases.begin(); iter != m_proposedDatabases.end(); ++iter)
+ if ((*iter)->details().name() == name && (*iter)->origin()->equal(origin))
+ return String();
+ }
return m_server->fullPathForDatabase(origin, name, createIfDoesNotExist);
}
@@ -392,10 +405,13 @@
DatabaseDetails DatabaseManager::detailsForNameAndOrigin(const String& name, SecurityOrigin* origin)
{
- ProposedDatabase* db = m_proposedDatabase;
- if (db && db->details().name() == name && db->origin()->equal(origin)) {
- ASSERT(db->details().thread() == currentThread() || isMainThread());
- return db->details();
+ {
+ MutexLocker locker(m_lock);
+ for (HashSet<ProposedDatabase*>::iterator iter = m_proposedDatabases.begin(); iter != m_proposedDatabases.end(); ++iter)
+ if ((*iter)->details().name() == name && (*iter)->origin()->equal(origin)) {
+ ASSERT((*iter)->details().thread() == currentThread() || isMainThread());
+ return (*iter)->details();
+ }
}
return m_server->detailsForNameAndOrigin(name, origin);
}
Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h (158057 => 158058)
--- trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h 2013-10-25 22:01:35 UTC (rev 158057)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseManager.h 2013-10-25 22:03:40 UTC (rev 158058)
@@ -33,6 +33,7 @@
#include "DatabaseError.h"
#include <wtf/Assertions.h>
#include <wtf/HashMap.h>
+#include <wtf/HashSet.h>
#include <wtf/PassRefPtr.h>
#include <wtf/Threading.h>
@@ -132,22 +133,26 @@
DatabaseType, const String& name, const String& expectedVersion, const String& displayName,
unsigned long estimatedSize, bool setVersionInNewDatabase, DatabaseError&, String& errorMessage);
+ void addProposedDatabase(ProposedDatabase*);
+ void removeProposedDatabase(ProposedDatabase*);
+
static void logErrorMessage(ScriptExecutionContext*, const String& message);
AbstractDatabaseServer* m_server;
DatabaseManagerClient* m_client;
bool m_databaseIsAvailable;
- // Access to the following fields require locking m_contextMapLock:
+ // Access to the following fields require locking m_lock below:
typedef HashMap<ScriptExecutionContext*, DatabaseContext*> ContextMap;
ContextMap m_contextMap;
#if !ASSERT_DISABLED
int m_databaseContextRegisteredCount;
int m_databaseContextInstanceCount;
#endif
- Mutex m_contextMapLock;
+ HashSet<ProposedDatabase*> m_proposedDatabases;
- ProposedDatabase* m_proposedDatabase;
+ // This lock protects m_contextMap, and m_proposedDatabases.
+ Mutex m_lock;
};
} // namespace WebCore