Changeset 57317 in webkit
- Timestamp:
- Apr 9, 2010 1:15:04 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r57316 r57317 1 2010-04-09 Sheriff Bot <webkit.review.bot@gmail.com> 2 3 Unreviewed, rolling out r57286. 4 http://trac.webkit.org/changeset/57286 5 https://bugs.webkit.org/show_bug.cgi?id=37312 6 7 "Caused intermittent test failures on all Mac bots." 8 (Requested by eseidel on #webkit). 9 10 * storage/DatabaseTracker.cpp: 11 (WebCore::DatabaseTracker::originQuotaManagerNoLock): 12 (WebCore::DatabaseTracker::originQuotaManager): 13 (WebCore::DatabaseTracker::DatabaseTracker): 14 (WebCore::DatabaseTracker::canEstablishDatabase): 15 (WebCore::DatabaseTracker::hasEntryForOrigin): 16 (WebCore::DatabaseTracker::getMaxSizeForDatabase): 17 (WebCore::DatabaseTracker::fullPathForDatabaseNoLock): 18 (WebCore::DatabaseTracker::fullPathForDatabase): 19 (WebCore::DatabaseTracker::populateOrigins): 20 (WebCore::DatabaseTracker::origins): 21 (WebCore::DatabaseTracker::databaseNamesForOrigin): 22 (WebCore::DatabaseTracker::addOpenDatabase): 23 (WebCore::DatabaseTracker::removeOpenDatabase): 24 (WebCore::DatabaseTracker::usageForOriginNoLock): 25 (WebCore::DatabaseTracker::usageForOrigin): 26 (WebCore::DatabaseTracker::quotaForOrigin): 27 (WebCore::DatabaseTracker::setQuota): 28 (WebCore::DatabaseTracker::deleteOrigin): 29 (WebCore::DatabaseTracker::deleteDatabase): 30 (WebCore::DatabaseTracker::deleteDatabaseFile): 31 * storage/DatabaseTracker.h: 32 * storage/SQLTransactionClient.cpp: 33 (WebCore::SQLTransactionClient::didExecuteStatement): 34 1 35 2010-04-09 Andras Becsi <abecsi@webkit.org> 2 36 -
trunk/WebCore/storage/DatabaseTracker.cpp
r57286 r57317 50 50 using namespace std; 51 51 52 static WebCore::OriginQuotaManager& originQuotaManager()53 {54 DEFINE_STATIC_LOCAL(WebCore::OriginQuotaManager, quotaManager, ());55 return quotaManager;56 }57 58 52 namespace WebCore { 53 54 OriginQuotaManager& DatabaseTracker::originQuotaManagerNoLock() 55 { 56 ASSERT(m_quotaManager); 57 return *m_quotaManager; 58 } 59 60 OriginQuotaManager& DatabaseTracker::originQuotaManager() 61 { 62 MutexLocker lockDatabase(m_databaseGuard); 63 populateOrigins(); 64 return originQuotaManagerNoLock(); 65 } 59 66 60 67 DatabaseTracker& DatabaseTracker::tracker() … … 68 75 { 69 76 SQLiteFileSystem::registerSQLiteVFS(); 70 71 MutexLocker lockDatabase(m_databaseGuard);72 populateOrigins();73 77 } 74 78 … … 129 133 unsigned long long tempUsage; 130 134 { 135 Locker<OriginQuotaManager> locker(originQuotaManager()); 131 136 MutexLocker lockDatabase(m_databaseGuard); 132 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager());133 137 134 138 if (!canCreateDatabase(origin, name)) … … 136 140 137 141 recordCreatingDatabase(origin, name); 142 143 populateOrigins(); 138 144 139 145 // Since we're imminently opening a database within this context's origin, make sure this origin is being tracked by the QuotaTracker … … 187 193 { 188 194 MutexLocker lockDatabase(m_databaseGuard); 195 populateOrigins(); 189 196 return hasEntryForOriginNoLock(origin); 190 197 } … … 212 219 // The maximum size for a database is the full quota for its origin, minus the current usage within the origin, 213 220 // plus the current usage of the given database 214 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager());221 Locker<OriginQuotaManager> locker(originQuotaManager()); 215 222 SecurityOrigin* origin = database->securityOrigin(); 216 223 return quotaForOrigin(origin) - originQuotaManager().diskUsage(origin) + SQLiteFileSystem::getDatabaseFileSize(database->fileName()); 217 224 } 218 225 219 void DatabaseTracker::databaseChanged(Database* database)220 {221 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager());222 originQuotaManager().markDatabase(database);223 }224 225 226 String DatabaseTracker::originPath(SecurityOrigin* origin) const 226 227 { … … 231 232 { 232 233 ASSERT(!m_databaseGuard.tryLock()); 233 ASSERT(!originQuotaManager ().tryLock());234 ASSERT(!originQuotaManagerNoLock().tryLock()); 234 235 235 236 for (HashSet<ProposedDatabase*>::iterator iter = m_proposedDatabases.begin(); iter != m_proposedDatabases.end(); ++iter) … … 275 276 // to the quota manager now 276 277 String fullFilePath = SQLiteFileSystem::appendDatabaseFileNameToPath(originPath, fileName); 277 if (originQuotaManager ().tracksOrigin(origin))278 originQuotaManager ().addDatabase(origin, name, fullFilePath);278 if (originQuotaManagerNoLock().tracksOrigin(origin)) 279 originQuotaManagerNoLock().addDatabase(origin, name, fullFilePath); 279 280 280 281 return fullFilePath; … … 283 284 String DatabaseTracker::fullPathForDatabase(SecurityOrigin* origin, const String& name, bool createIfNotExists) 284 285 { 285 MutexLocker lockDatabase(m_databaseGuard); 286 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 286 Locker<OriginQuotaManager> locker(originQuotaManager()); 287 MutexLocker lockDatabase(m_databaseGuard); 288 populateOrigins(); 287 289 288 290 return fullPathForDatabaseNoLock(origin, name, createIfNotExists).threadsafeCopy(); … … 296 298 297 299 m_quotaMap.set(new QuotaMap); 300 if (!m_quotaManager) 301 m_quotaManager.set(new OriginQuotaManager); 298 302 299 303 openTrackerDatabase(false); … … 321 325 { 322 326 MutexLocker lockDatabase(m_databaseGuard); 327 populateOrigins(); 323 328 ASSERT(m_quotaMap); 324 329 copyKeysToVector(*m_quotaMap, result); … … 353 358 bool DatabaseTracker::databaseNamesForOrigin(SecurityOrigin* origin, Vector<String>& resultVector) 354 359 { 360 MutexLocker lockDatabase(m_databaseGuard); 355 361 Vector<String> temp; 356 { 357 MutexLocker lockDatabase(m_databaseGuard); 358 if (!databaseNamesForOriginNoLock(origin, temp)) 359 return false; 360 } 362 if (!databaseNamesForOriginNoLock(origin, temp)) 363 return false; 361 364 362 365 for (Vector<String>::iterator iter = temp.begin(); iter != temp.end(); ++iter) … … 471 474 return; 472 475 473 { 474 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard); 475 476 if (!m_openDatabaseMap) 477 m_openDatabaseMap.set(new DatabaseOriginMap); 478 479 String name(database->stringIdentifier()); 480 DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin()); 481 if (!nameMap) { 482 nameMap = new DatabaseNameMap; 483 m_openDatabaseMap->set(database->securityOrigin()->threadsafeCopy(), nameMap); 484 } 485 486 DatabaseSet* databaseSet = nameMap->get(name); 487 if (!databaseSet) { 488 databaseSet = new DatabaseSet; 489 nameMap->set(name.threadsafeCopy(), databaseSet); 490 } 491 492 databaseSet->add(database); 493 494 LOG(StorageAPI, "Added open Database %s (%p)\n", database->stringIdentifier().ascii().data(), database); 495 } 476 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard); 477 478 if (!m_openDatabaseMap) 479 m_openDatabaseMap.set(new DatabaseOriginMap); 480 481 String name(database->stringIdentifier()); 482 DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin()); 483 if (!nameMap) { 484 nameMap = new DatabaseNameMap; 485 m_openDatabaseMap->set(database->securityOrigin()->threadsafeCopy(), nameMap); 486 } 487 488 DatabaseSet* databaseSet = nameMap->get(name); 489 if (!databaseSet) { 490 databaseSet = new DatabaseSet; 491 nameMap->set(name.threadsafeCopy(), databaseSet); 492 } 493 494 databaseSet->add(database); 495 496 LOG(StorageAPI, "Added open Database %s (%p)\n", database->stringIdentifier().ascii().data(), database); 496 497 497 498 MutexLocker lockDatabase(m_databaseGuard); … … 504 505 return; 505 506 506 {507 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard);508 509 if (!m_openDatabaseMap) {510 ASSERT_NOT_REACHED();511 return;512 }513 514 String name(database->stringIdentifier());515 DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin());516 if (!nameMap) {517 ASSERT_NOT_REACHED();518 return;519 }520 521 DatabaseSet* databaseSet = nameMap->get(name);522 if (!databaseSet) {523 ASSERT_NOT_REACHED();524 return;525 }526 527 databaseSet->remove(database);528 529 LOG(StorageAPI, "Removed open Database %s (%p)\n", database->stringIdentifier().ascii().data(), database);530 531 if (!databaseSet->isEmpty())532 return;533 534 nameMap->remove(name);535 delete databaseSet;536 537 if (!nameMap->isEmpty())538 return;539 540 m_openDatabaseMap->remove(database->securityOrigin());541 delete nameMap;542 }543 544 507 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 545 originQuotaManager().removeOrigin(database->securityOrigin()); 508 MutexLocker lockDatabase(m_databaseGuard); 509 MutexLocker openDatabaseMapLock(m_openDatabaseMapGuard); 510 511 if (!m_openDatabaseMap) { 512 ASSERT_NOT_REACHED(); 513 return; 514 } 515 516 String name(database->stringIdentifier()); 517 DatabaseNameMap* nameMap = m_openDatabaseMap->get(database->securityOrigin()); 518 if (!nameMap) { 519 ASSERT_NOT_REACHED(); 520 return; 521 } 522 523 DatabaseSet* databaseSet = nameMap->get(name); 524 if (!databaseSet) { 525 ASSERT_NOT_REACHED(); 526 return; 527 } 528 529 databaseSet->remove(database); 530 531 LOG(StorageAPI, "Removed open Database %s (%p)\n", database->stringIdentifier().ascii().data(), database); 532 533 if (!databaseSet->isEmpty()) 534 return; 535 536 nameMap->remove(name); 537 delete databaseSet; 538 539 if (!nameMap->isEmpty()) 540 return; 541 542 m_openDatabaseMap->remove(database->securityOrigin()); 543 delete nameMap; 544 originQuotaManagerNoLock().removeOrigin(database->securityOrigin()); 546 545 } 547 546 … … 566 565 unsigned long long DatabaseTracker::usageForOriginNoLock(SecurityOrigin* origin) 567 566 { 568 ASSERT(!originQuotaManager ().tryLock());567 ASSERT(!originQuotaManagerNoLock().tryLock()); 569 568 570 569 // Use the OriginQuotaManager mechanism to calculate the usage 571 if (originQuotaManager ().tracksOrigin(origin))572 return originQuotaManager ().diskUsage(origin);570 if (originQuotaManagerNoLock().tracksOrigin(origin)) 571 return originQuotaManagerNoLock().diskUsage(origin); 573 572 574 573 // If the OriginQuotaManager doesn't track this origin already, prime it to do so 575 originQuotaManager ().trackOrigin(origin);574 originQuotaManagerNoLock().trackOrigin(origin); 576 575 577 576 Vector<String> names; … … 579 578 580 579 for (unsigned i = 0; i < names.size(); ++i) 581 originQuotaManager ().addDatabase(origin, names[i], fullPathForDatabaseNoLock(origin, names[i], false));582 583 if (!originQuotaManager ().tracksOrigin(origin))580 originQuotaManagerNoLock().addDatabase(origin, names[i], fullPathForDatabaseNoLock(origin, names[i], false)); 581 582 if (!originQuotaManagerNoLock().tracksOrigin(origin)) 584 583 return 0; 585 return originQuotaManager ().diskUsage(origin);584 return originQuotaManagerNoLock().diskUsage(origin); 586 585 } 587 586 588 587 unsigned long long DatabaseTracker::usageForOrigin(SecurityOrigin* origin) 589 588 { 590 MutexLocker lockDatabase(m_databaseGuard);591 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 589 Locker<OriginQuotaManager> locker(originQuotaManager()); 590 592 591 return usageForOriginNoLock(origin); 593 592 } … … 603 602 { 604 603 MutexLocker lockDatabase(m_databaseGuard); 604 populateOrigins(); 605 605 return quotaForOriginNoLock(origin); 606 606 } … … 610 610 MutexLocker lockDatabase(m_databaseGuard); 611 611 612 populateOrigins(); 612 613 if (quotaForOriginNoLock(origin) == quota) 613 614 return; … … 721 722 722 723 { 724 // To satisfy the lock hierarchy, we have to lock the originQuotaManager before m_databaseGuard if there's any chance we'll to lock both. 725 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 723 726 MutexLocker lockDatabase(m_databaseGuard); 727 SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=?"); 728 724 729 doneDeletingOrigin(origin); 725 730 726 SQLiteStatement statement(m_database, "DELETE FROM Databases WHERE origin=?");727 731 if (statement.prepare() != SQLResultOk) { 728 732 LOG_ERROR("Unable to prepare deletion of databases from origin %s from tracker", origin->databaseIdentifier().ascii().data()); … … 755 759 m_quotaMap->remove(origin); 756 760 757 { 758 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 759 originQuotaManager().removeOrigin(origin); 760 } 761 originQuotaManagerNoLock().removeOrigin(origin); 761 762 762 763 // If we removed the last origin, do some additional deletion. … … 913 914 } 914 915 916 // To satisfy the lock hierarchy, we have to lock the originQuotaManager before m_databaseGuard if there's any chance we'll to lock both. 917 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 915 918 MutexLocker lockDatabase(m_databaseGuard); 916 919 … … 931 934 } 932 935 933 { 934 Locker<OriginQuotaManager> quotaManagerLocker(originQuotaManager()); 935 originQuotaManager().removeDatabase(origin, name); 936 } 936 originQuotaManagerNoLock().removeDatabase(origin, name); 937 937 938 938 if (m_client) { … … 955 955 #ifndef NDEBUG 956 956 { 957 958 957 MutexLocker lockDatabase(m_databaseGuard); 958 ASSERT(deletingDatabase(origin, name) || deletingOrigin(origin)); 959 959 } 960 960 #endif -
trunk/WebCore/storage/DatabaseTracker.h
r57286 r57317 53 53 #if !PLATFORM(CHROMIUM) 54 54 class DatabaseTrackerClient; 55 class OriginQuotaManager; 55 56 56 57 struct SecurityOriginTraits; … … 62 63 // This singleton will potentially be used from multiple worker threads and the page's context thread simultaneously. To keep this safe, it's 63 64 // currently using 4 locks. In order to avoid deadlock when taking multiple locks, you must take them in the correct order: 64 // m_databaseGuard before originQuotaManager() if both locks are needed.65 // m_ openDatabaseMapGuard is currently independent of the other locks.65 // originQuotaManager() before m_databaseGuard or m_openDatabaseMapGuard 66 // m_databaseGuard before m_openDatabaseMapGuard 66 67 // notificationMutex() is currently independent of the other locks. 67 68 … … 75 76 76 77 unsigned long long getMaxSizeForDatabase(const Database*); 77 void databaseChanged(Database*);78 78 79 79 private: … … 111 111 void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name); 112 112 113 OriginQuotaManager& originQuotaManager(); 114 115 113 116 bool hasEntryForOrigin(SecurityOrigin*); 114 117 115 118 private: 119 OriginQuotaManager& originQuotaManagerNoLock(); 116 120 bool hasEntryForOriginNoLock(SecurityOrigin* origin); 117 121 String fullPathForDatabaseNoLock(SecurityOrigin*, const String& name, bool createIfDoesNotExist); … … 138 142 typedef HashMap<RefPtr<SecurityOrigin>, unsigned long long, SecurityOriginHash> QuotaMap; 139 143 mutable OwnPtr<QuotaMap> m_quotaMap; 144 145 OwnPtr<OriginQuotaManager> m_quotaManager; 140 146 141 147 String m_databaseDirectoryPath; -
trunk/WebCore/storage/SQLTransactionClient.cpp
r57286 r57317 40 40 #include "DatabaseTracker.h" 41 41 #include "Document.h" 42 #include "OriginQuotaManager.h" 42 43 #include "Page.h" 43 44 #include "SQLTransaction.h" … … 56 57 { 57 58 ASSERT(currentThread() == transaction->database()->scriptExecutionContext()->databaseThread()->getThreadID()); 58 DatabaseTracker::tracker().databaseChanged(transaction->database()); 59 OriginQuotaManager& manager(DatabaseTracker::tracker().originQuotaManager()); 60 Locker<OriginQuotaManager> locker(manager); 61 manager.markDatabase(transaction->database()); 59 62 } 60 63
Note: See TracChangeset
for help on using the changeset viewer.