Changeset 96554 in webkit
- Timestamp:
- Oct 3, 2011 4:07:35 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r96553 r96554 1 2011-10-03 Michael Nordman <michaeln@google.com> 2 3 A little more WebSQLDatabase thread safety. 4 https://bugs.webkit.org/show_bug.cgi?id=69277 5 6 - switch to using AtomicallyInitializedStatic where appropiate 7 - avoid using some Strings across threads 8 9 Reviewed by David Levin. 10 11 Existing tests apply. 12 13 * storage/AbstractDatabase.cpp: 14 (WebCore::guidMutex): 15 (WebCore::guidToVersionMap): 16 (WebCore::guidToDatabaseMap): 17 (WebCore::guidForOriginAndName): 18 (WebCore::AbstractDatabase::databaseInfoTableName): 19 (WebCore::AbstractDatabase::AbstractDatabase): 20 (WebCore::AbstractDatabase::performOpenAndVerify): 21 (WebCore::AbstractDatabase::getVersionFromDatabase): 22 (WebCore::AbstractDatabase::setVersionInDatabase): 23 * storage/AbstractDatabase.h: 24 * storage/chromium/DatabaseTrackerChromium.cpp: 25 (WebCore::DatabaseTracker::tracker): 26 * storage/chromium/QuotaTracker.cpp: 27 (WebCore::QuotaTracker::instance): 28 1 29 2011-10-03 Ryosuke Niwa <rniwa@webkit.org> 2 30 -
trunk/Source/WebCore/storage/AbstractDatabase.cpp
r95901 r96554 1 1 /* 2 * Copyright (C) 201 0Google Inc. All rights reserved.2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 49 49 namespace WebCore { 50 50 51 static const char versionKey[] = "WebKitDatabaseVersionKey"; 52 static const char infoTableName[] = "__WebKitDatabaseInfoTable__"; 53 51 54 static bool retrieveTextResultFromDatabase(SQLiteDatabase& db, const String& query, String& resultString) 52 55 { … … 97 100 static Mutex& guidMutex() 98 101 { 99 // Note: We don't have to use AtomicallyInitializedStatic here because 100 // this function is called once in the constructor on the main thread 101 // before any other threads that call this function are used. 102 DEFINE_STATIC_LOCAL(Mutex, mutex, ()); 102 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); 103 103 return mutex; 104 104 } … … 107 107 static GuidVersionMap& guidToVersionMap() 108 108 { 109 // Ensure the the mutex is locked. 110 ASSERT(!guidMutex().tryLock()); 109 111 DEFINE_STATIC_LOCAL(GuidVersionMap, map, ()); 110 112 return map; … … 130 132 static GuidDatabaseMap& guidToDatabaseMap() 131 133 { 134 // Ensure the the mutex is locked. 135 ASSERT(!guidMutex().tryLock()); 132 136 DEFINE_STATIC_LOCAL(GuidDatabaseMap, map, ()); 133 137 return map; … … 136 140 static int guidForOriginAndName(const String& origin, const String& name) 137 141 { 142 // Ensure the the mutex is locked. 143 ASSERT(!guidMutex().tryLock()); 144 138 145 String stringID = origin + "/" + name; 139 146 140 // Note: We don't have to use AtomicallyInitializedStatic here because141 // this function is called once in the constructor on the main thread142 // before any other threads that call this function are used.143 DEFINE_STATIC_LOCAL(Mutex, stringIdentifierMutex, ());144 MutexLocker locker(stringIdentifierMutex);145 147 typedef HashMap<String, int> IDGuidMap; 146 148 DEFINE_STATIC_LOCAL(IDGuidMap, stringIdentifierToGUIDMap, ()); … … 168 170 169 171 // static 170 const String& AbstractDatabase::databaseInfoTableName() 171 { 172 DEFINE_STATIC_LOCAL(String, name, ("__WebKitDatabaseInfoTable__")); 173 return name; 172 const char* AbstractDatabase::databaseInfoTableName() 173 { 174 return infoTableName; 174 175 } 175 176 … … 188 189 m_contextThreadSecurityOrigin = m_scriptExecutionContext->securityOrigin(); 189 190 190 m_databaseAuthorizer = DatabaseAuthorizer::create( databaseInfoTableName());191 m_databaseAuthorizer = DatabaseAuthorizer::create(infoTableName); 191 192 192 193 if (m_name.isNull()) 193 194 m_name = ""; 194 195 195 m_guid = guidForOriginAndName(securityOrigin()->toString(), name);196 196 { 197 197 MutexLocker locker(guidMutex()); 198 198 m_guid = guidForOriginAndName(securityOrigin()->toString(), name); 199 199 HashSet<AbstractDatabase*>* hashSet = guidToDatabaseMap().get(m_guid); 200 200 if (!hashSet) { … … 265 265 if (entry != guidToVersionMap().end()) { 266 266 // Map null string to empty string (see updateGuidVersionMap()). 267 currentVersion = entry->second.isNull() ? String("") : entry->second ;267 currentVersion = entry->second.isNull() ? String("") : entry->second.threadsafeCopy(); 268 268 LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data()); 269 269 … … 272 272 // we cannot read the actual version from the database without potentially 273 273 // inducing a form of deadlock, a busytimeout error when trying to 274 // access the database. So we'll use the cached value if we're able to read275 // the value without waiting, and otherwise use the cached value (which may be off).274 // access the database. So we'll use the cached value if we're unable to read 275 // the value from the database file without waiting. 276 276 // FIXME: Add an async openDatabase method to the DatabaseAPI. 277 277 const int noSqliteBusyWaitTime = 0; … … 296 296 } 297 297 298 if (!m_sqliteDatabase.tableExists(databaseInfoTableName())) { 298 String tableName(infoTableName); 299 if (!m_sqliteDatabase.tableExists(tableName)) { 299 300 m_new = true; 300 301 301 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);")) {302 LOG_ERROR("Unable to create table %s in database %s", databaseInfoTableName().ascii().data(), databaseDebugName().ascii().data());302 if (!m_sqliteDatabase.executeCommand("CREATE TABLE " + tableName + " (key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,value TEXT NOT NULL ON CONFLICT FAIL);")) { 303 LOG_ERROR("Unable to create table %s in database %s", infoTableName, databaseDebugName().ascii().data()); 303 304 ec = INVALID_STATE_ERR; 304 305 transaction.rollback(); … … 391 392 } 392 393 393 // static394 const String& AbstractDatabase::databaseVersionKey()395 {396 DEFINE_STATIC_LOCAL(String, key, ("WebKitDatabaseVersionKey"));397 return key;398 }399 400 394 bool AbstractDatabase::getVersionFromDatabase(String& version, bool shouldCacheVersion) 401 395 { 402 DEFINE_STATIC_LOCAL(String, getVersionQuery, ("SELECT value FROM " + databaseInfoTableName() + " WHERE key = '" + databaseVersionKey() + "';"));396 String query(String("SELECT value FROM ") + infoTableName + " WHERE key = '" + versionKey + "';"); 403 397 404 398 m_databaseAuthorizer->disable(); 405 399 406 bool result = retrieveTextResultFromDatabase(m_sqliteDatabase, getVersionQuery.threadsafeCopy(), version);400 bool result = retrieveTextResultFromDatabase(m_sqliteDatabase, query, version); 407 401 if (result) { 408 402 if (shouldCacheVersion) … … 420 414 // The INSERT will replace an existing entry for the database with the new version number, due to the UNIQUE ON CONFLICT REPLACE 421 415 // clause in the CREATE statement (see Database::performOpenAndVerify()). 422 DEFINE_STATIC_LOCAL(String, setVersionQuery, ("INSERT INTO " + databaseInfoTableName() + " (key, value) VALUES ('" + databaseVersionKey() + "', ?);"));416 String query(String("INSERT INTO ") + infoTableName + " (key, value) VALUES ('" + versionKey + "', ?);"); 423 417 424 418 m_databaseAuthorizer->disable(); 425 419 426 bool result = setTextValueInDatabase(m_sqliteDatabase, setVersionQuery.threadsafeCopy(), version);420 bool result = setTextValueInDatabase(m_sqliteDatabase, query, version); 427 421 if (result) { 428 422 if (shouldCacheVersion) 429 423 setCachedVersion(version); 430 424 } else 431 LOG_ERROR("Failed to set version %s in database (%s)", version.ascii().data(), setVersionQuery.ascii().data());425 LOG_ERROR("Failed to set version %s in database (%s)", version.ascii().data(), query.ascii().data()); 432 426 433 427 m_databaseAuthorizer->enable(); -
trunk/Source/WebCore/storage/AbstractDatabase.h
r95901 r96554 1 1 /* 2 * Copyright (C) 201 0Google Inc. All rights reserved.2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 105 105 bool getActualVersionForTransaction(String& version); 106 106 107 static const String&databaseInfoTableName();107 static const char* databaseInfoTableName(); 108 108 109 109 RefPtr<ScriptExecutionContext> m_scriptExecutionContext; … … 121 121 122 122 private: 123 static const String& databaseVersionKey();124 125 123 int m_guid; 126 124 bool m_opened; -
trunk/Source/WebCore/storage/chromium/DatabaseTrackerChromium.cpp
r95901 r96554 1 1 /* 2 * Copyright (C) 201 0Google Inc. All rights reserved.2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 48 48 DatabaseTracker& DatabaseTracker::tracker() 49 49 { 50 DEFINE_STATIC_LOCAL(DatabaseTracker, tracker,(""));50 AtomicallyInitializedStatic(DatabaseTracker&, tracker = *new DatabaseTracker("")); 51 51 return tracker; 52 52 } -
trunk/Source/WebCore/storage/chromium/QuotaTracker.cpp
r95901 r96554 1 1 /* 2 * Copyright (C) 20 09Google Inc. All rights reserved.2 * Copyright (C) 2011 Google Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 41 41 QuotaTracker& QuotaTracker::instance() 42 42 { 43 DEFINE_STATIC_LOCAL(QuotaTracker, tracker, ());43 AtomicallyInitializedStatic(QuotaTracker&, tracker = *new QuotaTracker); 44 44 return tracker; 45 45 }
Note: See TracChangeset
for help on using the changeset viewer.