Changeset 197474 in webkit
- Timestamp:
- Mar 2, 2016 4:23:47 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r197471 r197474 1 2016-03-02 Brady Eidson <beidson@apple.com> 2 3 Modern IDB: Close UniqueIDBDatabases once they become unused. 4 https://bugs.webkit.org/show_bug.cgi?id=154922 5 6 Reviewed by Alex Christensen. 7 8 * platform/mac-wk1/TestExpectations: 9 * storage/indexeddb/modern/256-open-databases-expected.txt: Added. 10 * storage/indexeddb/modern/256-open-databases.html: Added. 11 * storage/indexeddb/modern/exceed-open-file-limit-expected.txt: Added. 12 * storage/indexeddb/modern/exceed-open-file-limit.html: Added. 13 * storage/indexeddb/modern/resources/256-open-databases.js: Added. 14 * storage/indexeddb/modern/resources/exceed-open-file-limit.js: Added. 15 1 16 2016-03-02 Ryan Haddad <ryanhaddad@apple.com> 2 17 -
trunk/LayoutTests/platform/mac-wk1/TestExpectations
r197378 r197474 147 147 webkit.org/b/152178 [ Yosemite+ ] fast/replaced/replaced-breaking.html [ Failure ] 148 148 149 # DRT can open way more files than the DatabaseProcess with WebKitTestRunner, and the number is reasonable. 150 # So we shouldn't bother with this test in WebKit1. 151 storage/indexeddb/modern/exceed-open-file-limit.html 152 149 153 ### END OF (2) Failures without bug reports 150 154 ######################################## -
trunk/Source/WebCore/ChangeLog
r197472 r197474 1 2016-03-02 Brady Eidson <beidson@apple.com> 2 3 Modern IDB: Close UniqueIDBDatabases once they become unused. 4 https://bugs.webkit.org/show_bug.cgi?id=154922 5 6 Reviewed by Alex Christensen. 7 8 Tests: storage/indexeddb/modern/256-open-databases.html 9 storage/indexeddb/modern/exceed-open-file-limit.html 10 11 Without this change, attempts to open a 256th database in the DatabaseProcess will fail on Mac. 12 13 Due to SQLite journal files, this limit could come up as early as 128 databases if they are all 14 in active use. 15 16 This is because launchd - by default - limits xpc services to having 256 open file handles by default. 17 18 While we should explore raising the limit, we should also close databases we no longer need. 19 20 * Modules/indexeddb/server/IDBBackingStore.h: 21 22 * Modules/indexeddb/server/IDBServer.cpp: 23 (WebCore::IDBServer::IDBServer::closeUniqueIDBDatabase): 24 (WebCore::IDBServer::IDBServer::deleteUniqueIDBDatabase): Deleted. 25 * Modules/indexeddb/server/IDBServer.h: 26 27 * Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp: 28 (WebCore::IDBServer::MemoryBackingStoreTransaction::MemoryBackingStoreTransaction): 29 30 * Modules/indexeddb/server/MemoryIDBBackingStore.cpp: 31 (WebCore::IDBServer::MemoryIDBBackingStore::getOrEstablishDatabaseInfo): 32 * Modules/indexeddb/server/MemoryIDBBackingStore.h: 33 34 * Modules/indexeddb/server/SQLiteIDBBackingStore.cpp: 35 (WebCore::IDBServer::SQLiteIDBBackingStore::getOrEstablishDatabaseInfo): 36 * Modules/indexeddb/server/SQLiteIDBBackingStore.h: 37 38 * Modules/indexeddb/server/UniqueIDBDatabase.cpp: 39 (WebCore::IDBServer::UniqueIDBDatabase::UniqueIDBDatabase): 40 (WebCore::IDBServer::UniqueIDBDatabase::~UniqueIDBDatabase): 41 (WebCore::IDBServer::UniqueIDBDatabase::performCurrentOpenOperation): Handle the case where opening 42 the backing store failed by firing an error event instead of pretending everything is okay. 43 (WebCore::IDBServer::UniqueIDBDatabase::deleteBackingStore): 44 (WebCore::IDBServer::UniqueIDBDatabase::didDeleteBackingStore): 45 (WebCore::IDBServer::UniqueIDBDatabase::openBackingStore): 46 (WebCore::IDBServer::UniqueIDBDatabase::didOpenBackingStore): 47 (WebCore::IDBServer::UniqueIDBDatabase::isCurrentlyInUse): 48 (WebCore::IDBServer::UniqueIDBDatabase::operationAndTransactionTimerFired): If the database is not 49 currently in use, close it. 50 (WebCore::IDBServer::UniqueIDBDatabase::inProgressTransactionCompleted): 51 * Modules/indexeddb/server/UniqueIDBDatabase.h: 52 (WebCore::IDBServer::UniqueIDBDatabase::deletePending): Deleted. 53 54 * Modules/indexeddb/shared/IDBObjectStoreInfo.cpp: 55 (WebCore::IDBObjectStoreInfo::isolatedCopy): Actually get this right. 56 1 57 2016-03-02 Gavin Barraclough <barraclough@apple.com> 2 58 -
trunk/Source/WebCore/Modules/indexeddb/server/IDBBackingStore.h
r196191 r197474 55 55 virtual ~IDBBackingStore() { } 56 56 57 virtual const IDBDatabaseInfo& getOrEstablishDatabaseInfo() = 0;57 virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) = 0; 58 58 59 59 virtual IDBError beginTransaction(const IDBTransactionInfo&) = 0; … … 80 80 virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) = 0; 81 81 virtual void deleteBackingStore() = 0; 82 82 83 virtual bool supportsSimultaneousTransactions() = 0; 84 virtual bool isEphemeral() = 0; 83 85 }; 84 86 -
trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
r197231 r197474 158 158 } 159 159 160 void IDBServer:: deleteUniqueIDBDatabase(UniqueIDBDatabase& database)161 { 162 LOG(IndexedDB, "IDBServer:: deleteUniqueIDBDatabase");160 void IDBServer::closeUniqueIDBDatabase(UniqueIDBDatabase& database) 161 { 162 LOG(IndexedDB, "IDBServer::closeUniqueIDBDatabase"); 163 163 164 164 auto deletedDatabase = m_uniqueIDBDatabaseMap.take(database.identifier()); -
trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h
r196779 r197474 88 88 void unregisterTransaction(UniqueIDBDatabaseTransaction&); 89 89 90 void deleteUniqueIDBDatabase(UniqueIDBDatabase&);90 void closeUniqueIDBDatabase(UniqueIDBDatabase&); 91 91 92 92 std::unique_ptr<IDBBackingStore> createBackingStore(const IDBDatabaseIdentifier&); -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryBackingStoreTransaction.cpp
r194859 r197474 48 48 , m_info(info) 49 49 { 50 if (m_info.mode() == IndexedDB::TransactionMode::VersionChange) 51 m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(m_backingStore.getOrEstablishDatabaseInfo()); 50 if (m_info.mode() == IndexedDB::TransactionMode::VersionChange) { 51 IDBDatabaseInfo info; 52 auto error = m_backingStore.getOrEstablishDatabaseInfo(info); 53 if (error.isNull()) 54 m_originalDatabaseInfo = std::make_unique<IDBDatabaseInfo>(info); 55 } 52 56 } 53 57 -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.cpp
r196191 r197474 56 56 } 57 57 58 const IDBDatabaseInfo& MemoryIDBBackingStore::getOrEstablishDatabaseInfo()58 IDBError MemoryIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info) 59 59 { 60 60 if (!m_databaseInfo) 61 61 m_databaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0); 62 62 63 return *m_databaseInfo; 63 info = *m_databaseInfo; 64 return { }; 64 65 } 65 66 -
trunk/Source/WebCore/Modules/indexeddb/server/MemoryIDBBackingStore.h
r196191 r197474 47 47 virtual ~MemoryIDBBackingStore() override final; 48 48 49 virtual const IDBDatabaseInfo& getOrEstablishDatabaseInfo() override final;49 virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) override final; 50 50 void setDatabaseInfo(const IDBDatabaseInfo&); 51 51 … … 72 72 virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final; 73 73 virtual void deleteBackingStore() override final; 74 74 75 virtual bool supportsSimultaneousTransactions() override final { return true; } 76 virtual bool isEphemeral() override final { return true; } 75 77 76 78 void removeObjectStoreForVersionChangeAbort(MemoryObjectStore&); -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.cpp
r197231 r197474 558 558 } 559 559 560 const IDBDatabaseInfo& SQLiteIDBBackingStore::getOrEstablishDatabaseInfo()560 IDBError SQLiteIDBBackingStore::getOrEstablishDatabaseInfo(IDBDatabaseInfo& info) 561 561 { 562 562 LOG(IndexedDB, "SQLiteIDBBackingStore::getOrEstablishDatabaseInfo - database %s", m_identifier.databaseName().utf8().data()); 563 563 564 if (m_databaseInfo) 565 return*m_databaseInfo;566 567 m_databaseInfo = std::make_unique<IDBDatabaseInfo>(m_identifier.databaseName(), 0);564 if (m_databaseInfo) { 565 info = *m_databaseInfo; 566 return { }; 567 } 568 568 569 569 makeAllDirectories(fullDatabaseDirectory()); … … 577 577 578 578 if (!m_sqliteDB) 579 return *m_databaseInfo;579 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to open database file on disk") }; 580 580 581 581 m_sqliteDB->setCollationFunction("IDBKEY", [this](int aLength, const void* a, int bLength, const void* b) { … … 586 586 LOG_ERROR("Error creating or migrating Records table in database"); 587 587 m_sqliteDB = nullptr; 588 return *m_databaseInfo;588 return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Records table in database") }; 589 589 } 590 590 … … 592 592 LOG_ERROR("Error creating or migrating Index Records table in database"); 593 593 m_sqliteDB = nullptr; 594 return *m_databaseInfo;594 return { IDBDatabaseException::UnknownError, ASCIILiteral("Error creating or migrating Index Records table in database") }; 595 595 } 596 596 … … 599 599 databaseInfo = createAndPopulateInitialDatabaseInfo(); 600 600 601 if (!databaseInfo) 601 if (!databaseInfo) { 602 602 LOG_ERROR("Unable to establish IDB database at path '%s'", dbFilename.utf8().data()); 603 else 604 m_databaseInfo = WTFMove(databaseInfo); 605 606 return *m_databaseInfo; 603 m_sqliteDB = nullptr; 604 return { IDBDatabaseException::UnknownError, ASCIILiteral("Unable to establish IDB database file") }; 605 } 606 607 m_databaseInfo = WTFMove(databaseInfo); 608 info = *m_databaseInfo; 609 return { }; 607 610 } 608 611 -
trunk/Source/WebCore/Modules/indexeddb/server/SQLiteIDBBackingStore.h
r196191 r197474 52 52 virtual ~SQLiteIDBBackingStore() override final; 53 53 54 virtual const IDBDatabaseInfo& getOrEstablishDatabaseInfo() override final;54 virtual IDBError getOrEstablishDatabaseInfo(IDBDatabaseInfo&) override final; 55 55 56 56 virtual IDBError beginTransaction(const IDBTransactionInfo&) override final; … … 76 76 virtual IDBObjectStoreInfo* infoForObjectStore(uint64_t objectStoreIdentifier) override final; 77 77 virtual void deleteBackingStore() override final; 78 78 79 virtual bool supportsSimultaneousTransactions() override final { return false; } 80 virtual bool isEphemeral() override final { return false; } 79 81 80 82 void unregisterCursor(SQLiteIDBCursor&); -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
r197231 r197474 51 51 , m_operationAndTransactionTimer(*this, &UniqueIDBDatabase::operationAndTransactionTimerFired) 52 52 { 53 LOG(IndexedDB, "UniqueIDBDatabase::UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data()); 53 54 } 54 55 55 56 UniqueIDBDatabase::~UniqueIDBDatabase() 56 57 { 57 LOG(IndexedDB, "UniqueIDBDatabase::~UniqueIDBDatabase() (%p) ", this);58 LOG(IndexedDB, "UniqueIDBDatabase::~UniqueIDBDatabase() (%p) %s", this, m_identifier.debugString().utf8().data()); 58 59 ASSERT(!hasAnyPendingCallbacks()); 59 60 ASSERT(m_inProgressTransactions.isEmpty()); … … 134 135 if (requestedVersion < m_databaseInfo->version()) { 135 136 auto result = IDBResultData::error(m_currentOpenDBRequest->requestData().requestIdentifier(), IDBError(IDBDatabaseException::VersionError)); 137 m_currentOpenDBRequest->connection().didOpenDatabase(result); 138 m_currentOpenDBRequest = nullptr; 139 140 return; 141 } 142 143 if (!m_backingStoreOpenError.isNull()) { 144 auto result = IDBResultData::error(m_currentOpenDBRequest->requestData().requestIdentifier(), m_backingStoreOpenError); 136 145 m_currentOpenDBRequest->connection().didOpenDatabase(result); 137 146 m_currentOpenDBRequest = nullptr; … … 215 224 m_backingStore = nullptr; 216 225 m_backingStoreSupportsSimultaneousTransactions = false; 226 m_backingStoreIsEphemeral = false; 217 227 } else { 218 228 auto backingStore = m_server.createBackingStore(identifier); 219 auto databaseInfo = backingStore->getOrEstablishDatabaseInfo(); 229 230 IDBDatabaseInfo databaseInfo; 231 auto error = backingStore->getOrEstablishDatabaseInfo(databaseInfo); 232 if (!error.isNull()) 233 LOG_ERROR("Error getting database info from database %s that we are trying to delete", identifier.debugString().utf8().data()); 234 220 235 deletedVersion = databaseInfo.version(); 221 236 backingStore->deleteBackingStore(); … … 249 264 m_currentOpenDBRequest = nullptr; 250 265 251 m_deletePending = false;252 266 m_deleteBackingStoreInProgress = false; 253 267 254 268 if (m_closePendingDatabaseConnections.isEmpty()) { 255 269 if (m_pendingOpenDBRequests.isEmpty()) 256 m_server. deleteUniqueIDBDatabase(*this);270 m_server.closeUniqueIDBDatabase(*this); 257 271 else 258 272 invokeOperationAndTransactionTimer(); … … 465 479 m_backingStore = m_server.createBackingStore(identifier); 466 480 m_backingStoreSupportsSimultaneousTransactions = m_backingStore->supportsSimultaneousTransactions(); 467 auto databaseInfo = m_backingStore->getOrEstablishDatabaseInfo(); 468 469 m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo)); 470 } 471 472 void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info) 481 m_backingStoreIsEphemeral = m_backingStore->isEphemeral(); 482 483 IDBDatabaseInfo databaseInfo; 484 auto error = m_backingStore->getOrEstablishDatabaseInfo(databaseInfo); 485 486 m_server.postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo, error)); 487 } 488 489 void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info, const IDBError& error) 473 490 { 474 491 ASSERT(isMainThread()); … … 476 493 477 494 m_databaseInfo = std::make_unique<IDBDatabaseInfo>(info); 495 m_backingStoreOpenError = error; 478 496 479 497 ASSERT(m_isOpeningBackingStore); … … 1098 1116 } 1099 1117 1118 bool UniqueIDBDatabase::isCurrentlyInUse() const 1119 { 1120 return !m_openDatabaseConnections.isEmpty() || !m_closePendingDatabaseConnections.isEmpty() || !m_pendingOpenDBRequests.isEmpty() || m_currentOpenDBRequest || m_versionChangeDatabaseConnection || m_versionChangeTransaction || m_isOpeningBackingStore || m_deleteBackingStoreInProgress; 1121 } 1122 1100 1123 void UniqueIDBDatabase::invokeOperationAndTransactionTimer() 1101 1124 { … … 1110 1133 1111 1134 RefPtr<UniqueIDBDatabase> protector(this); 1135 1136 // This UniqueIDBDatabase might be no longer in use by any web page. 1137 // Assuming it is not ephemeral, the server should now close it to free up resources. 1138 if (!m_backingStoreIsEphemeral && !isCurrentlyInUse()) { 1139 ASSERT(m_pendingTransactions.isEmpty()); 1140 ASSERT(m_inProgressTransactions.isEmpty()); 1141 m_server.closeUniqueIDBDatabase(*this); 1142 return; 1143 } 1112 1144 1113 1145 // The current operation might require multiple attempts to handle, so try to … … 1260 1292 // If this transaction completing was the last of those operations, we can finally delete this UniqueIDBDatabase. 1261 1293 if (m_closePendingDatabaseConnections.isEmpty() && m_pendingOpenDBRequests.isEmpty() && !m_databaseInfo) { 1262 m_server. deleteUniqueIDBDatabase(*this);1294 m_server.closeUniqueIDBDatabase(*this); 1263 1295 return; 1264 1296 } -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
r197231 r197474 102 102 103 103 void handleDelete(IDBConnectionToClient&, const IDBRequestData&); 104 bool deletePending() const { return m_deletePending; }105 104 106 105 static JSC::VM& databaseThreadVM(); … … 147 146 // Main thread callbacks 148 147 void didDeleteBackingStore(uint64_t deletedVersion); 149 void didOpenBackingStore(const IDBDatabaseInfo& );148 void didOpenBackingStore(const IDBDatabaseInfo&, const IDBError&); 150 149 void didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError&, const IDBObjectStoreInfo&); 151 150 void didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError&, uint64_t objectStoreIdentifier); … … 174 173 175 174 bool hasAnyPendingCallbacks() const; 175 bool isCurrentlyInUse() const; 176 176 177 177 void invokeOperationAndTransactionTimer(); … … 192 192 193 193 bool m_isOpeningBackingStore { false }; 194 IDBError m_backingStoreOpenError; 194 195 std::unique_ptr<IDBBackingStore> m_backingStore; 195 196 std::unique_ptr<IDBDatabaseInfo> m_databaseInfo; … … 197 198 198 199 bool m_backingStoreSupportsSimultaneousTransactions { false }; 200 bool m_backingStoreIsEphemeral { false }; 199 201 200 202 HashMap<uint64_t, ErrorCallback> m_errorCallbacks; … … 213 215 HashSet<uint64_t> m_objectStoreWriteTransactions; 214 216 215 bool m_deletePending { false };216 217 bool m_deleteBackingStoreInProgress { false }; 217 218 }; -
trunk/Source/WebCore/Modules/indexeddb/shared/IDBObjectStoreInfo.cpp
r195527 r197474 89 89 IDBObjectStoreInfo result = { m_identifier, m_name.isolatedCopy(), m_keyPath.isolatedCopy(), m_autoIncrement }; 90 90 91 for (auto& iterator : m_indexMap) 91 for (auto& iterator : m_indexMap) { 92 92 result.m_indexMap.set(iterator.key, iterator.value.isolatedCopy()); 93 if (iterator.key > result.m_maxIndexID) 94 result.m_maxIndexID = iterator.key; 95 } 96 97 ASSERT(result.m_maxIndexID == m_maxIndexID); 93 98 94 99 return result;
Note: See TracChangeset
for help on using the changeset viewer.