Changeset 252839 in webkit
- Timestamp:
- Nov 23, 2019 7:03:26 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r252837 r252839 1 2019-11-23 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r252805. 4 https://bugs.webkit.org/show_bug.cgi?id=204553 5 6 Caused test failures and ASan crashes (Requested by ap on 7 #webkit). 8 9 Reverted changeset: 10 11 "Cross-thread version StorageQuotaManager" 12 https://bugs.webkit.org/show_bug.cgi?id=203971 13 https://trac.webkit.org/changeset/252805 14 1 15 2019-11-23 Zalan Bujtas <zalan@apple.com> 2 16 -
trunk/Source/WebCore/Headers.cmake
r252805 r252839 1382 1382 storage/StorageNamespaceProvider.h 1383 1383 storage/StorageQuotaManager.h 1384 storage/StorageQuotaUser.h 1384 1385 storage/StorageType.h 1385 1386 -
trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp
r252805 r252839 47 47 namespace IDBServer { 48 48 49 Ref<IDBServer> IDBServer::create(PAL::SessionID sessionID, StorageQuotaManagerSpaceRequester&& quotaManagerGetter)49 Ref<IDBServer> IDBServer::create(PAL::SessionID sessionID, QuotaManagerGetter&& quotaManagerGetter) 50 50 { 51 51 return adoptRef(*new IDBServer(sessionID, WTFMove(quotaManagerGetter))); 52 52 } 53 53 54 Ref<IDBServer> IDBServer::create(PAL::SessionID sessionID, const String& databaseDirectoryPath, StorageQuotaManagerSpaceRequester&& quotaManagerGetter)54 Ref<IDBServer> IDBServer::create(PAL::SessionID sessionID, const String& databaseDirectoryPath, QuotaManagerGetter&& quotaManagerGetter) 55 55 { 56 56 return adoptRef(*new IDBServer(sessionID, databaseDirectoryPath, WTFMove(quotaManagerGetter))); 57 57 } 58 58 59 IDBServer::IDBServer(PAL::SessionID sessionID, StorageQuotaManagerSpaceRequester&& spaceRequester)59 IDBServer::IDBServer(PAL::SessionID sessionID, QuotaManagerGetter&& quotaManagerGetter) 60 60 : CrossThreadTaskHandler("IndexedDatabase Server", AutodrainedPoolForRunLoop::Use) 61 61 , m_sessionID(sessionID) 62 , m_ spaceRequester(WTFMove(spaceRequester))63 { 64 } 65 66 IDBServer::IDBServer(PAL::SessionID sessionID, const String& databaseDirectoryPath, StorageQuotaManagerSpaceRequester&& spaceRequester)62 , m_quotaManagerGetter(WTFMove(quotaManagerGetter)) 63 { 64 } 65 66 IDBServer::IDBServer(PAL::SessionID sessionID, const String& databaseDirectoryPath, QuotaManagerGetter&& quotaManagerGetter) 67 67 : CrossThreadTaskHandler("IndexedDatabase Server", AutodrainedPoolForRunLoop::Use) 68 68 , m_sessionID(sessionID) 69 69 , m_databaseDirectoryPath(databaseDirectoryPath) 70 , m_ spaceRequester(WTFMove(spaceRequester))70 , m_quotaManagerGetter(WTFMove(quotaManagerGetter)) 71 71 { 72 72 LOG(IndexedDB, "IDBServer created at path %s", databaseDirectoryPath.utf8().data()); … … 684 684 void IDBServer::didPerformCloseAndDeleteDatabases(uint64_t callbackID) 685 685 { 686 for (auto& user : m_quotaUsers.values()) 687 user->resetSpaceUsed(); 688 686 689 auto callback = m_deleteDatabaseCompletionHandlers.take(callbackID); 687 690 ASSERT(callback); … … 689 692 } 690 693 691 StorageQuotaManager::Decision IDBServer::requestSpace(const ClientOrigin& origin, uint64_t taskSize) 694 IDBServer::QuotaUser::QuotaUser(IDBServer& server, StorageQuotaManager* manager, ClientOrigin&& origin) 695 : m_server(server) 696 , m_manager(makeWeakPtr(manager)) 697 , m_origin(WTFMove(origin)) 698 , m_isInitialized(m_server.m_sessionID.isEphemeral()) 699 { 700 if (manager) 701 manager->addUser(*this); 702 } 703 704 IDBServer::QuotaUser::~QuotaUser() 705 { 706 if (m_manager) 707 m_manager->removeUser(*this); 708 } 709 710 void IDBServer::QuotaUser::resetSpaceUsed() 711 { 712 m_spaceUsed = 0; 713 714 if (!m_manager) 715 return; 716 717 if (m_server.m_sessionID.isEphemeral()) 718 return; 719 720 if (!m_isInitialized) 721 return; 722 723 ASSERT(!m_initializationCallback); 724 725 m_isInitialized = false; 726 727 // Do add/remove to trigger call to whenInitialized. 728 m_manager->removeUser(*this); 729 m_manager->addUser(*this); 730 } 731 732 void IDBServer::QuotaUser::computeSpaceUsed() 733 { 734 resetSpaceUsed(); 735 } 736 737 void IDBServer::QuotaUser::increaseSpaceUsed(uint64_t size) 738 { 739 if (!m_isInitialized) 740 return; 741 ASSERT(m_spaceUsed + size > m_spaceUsed); 742 m_spaceUsed += size; 743 } 744 void IDBServer::QuotaUser::decreaseSpaceUsed(uint64_t size) 745 { 746 if (!m_isInitialized) 747 return; 748 ASSERT(m_spaceUsed >= size); 749 m_spaceUsed -= size; 750 } 751 752 void IDBServer::QuotaUser::whenInitialized(CompletionHandler<void()>&& callback) 753 { 754 if (m_isInitialized) { 755 callback(); 756 return; 757 } 758 m_initializationCallback = WTFMove(callback); 759 m_server.startComputingSpaceUsedForOrigin(m_origin); 760 } 761 762 void IDBServer::QuotaUser::initializeSpaceUsed(uint64_t spaceUsed) 763 { 764 ASSERT(m_isInitialized || !m_estimatedSpaceIncrease); 765 m_spaceUsed = spaceUsed; 766 m_isInitialized = true; 767 768 if (auto callback = WTFMove(m_initializationCallback)) 769 callback(); 770 } 771 772 IDBServer::QuotaUser& IDBServer::ensureQuotaUser(const ClientOrigin& origin) 773 { 774 return *m_quotaUsers.ensure(origin, [this, &origin] { 775 return makeUnique<QuotaUser>(*this, m_quotaManagerGetter(m_sessionID, origin), ClientOrigin { origin }); 776 }).iterator->value; 777 } 778 779 void IDBServer::startComputingSpaceUsedForOrigin(const ClientOrigin& origin) 780 { 781 ASSERT(!m_sessionID.isEphemeral()); 782 postDatabaseTask(createCrossThreadTask(*this, &IDBServer::computeSpaceUsedForOrigin, origin)); 783 } 784 785 void IDBServer::computeSpaceUsedForOrigin(const ClientOrigin& origin) 692 786 { 693 787 ASSERT(!isMainThread()); 694 return m_spaceRequester(origin, taskSize); 695 } 696 697 uint64_t IDBServer::diskUsage(const String& rootDirectory, const ClientOrigin& origin) 698 { 699 ASSERT(!isMainThread()); 700 701 auto oldVersionOriginDirectory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(origin.topOrigin, origin.clientOrigin, rootDirectory, "v0"_str); 702 auto newVersionOriginDirectory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(origin.topOrigin, origin.clientOrigin, rootDirectory, "v1"_str); 703 return SQLiteIDBBackingStore::databasesSizeForDirectory(oldVersionOriginDirectory) + SQLiteIDBBackingStore::databasesSizeForDirectory(newVersionOriginDirectory); 788 789 auto databaseDirectoryPath = this->databaseDirectoryPathIsolatedCopy(); 790 auto oldVersionOriginDirectory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(origin.topOrigin, origin.clientOrigin, databaseDirectoryPath, "v0"); 791 auto newVersionOriginDirectory = IDBDatabaseIdentifier::databaseDirectoryRelativeToRoot(origin.topOrigin, origin.clientOrigin, databaseDirectoryPath, "v1"); 792 auto size = SQLiteIDBBackingStore::databasesSizeForDirectory(oldVersionOriginDirectory) + SQLiteIDBBackingStore::databasesSizeForDirectory(newVersionOriginDirectory); 793 794 postDatabaseTaskReply(createCrossThreadTask(*this, &IDBServer::finishComputingSpaceUsedForOrigin, origin, size)); 795 } 796 797 void IDBServer::finishComputingSpaceUsedForOrigin(const ClientOrigin& origin, uint64_t spaceUsed) 798 { 799 ensureQuotaUser(origin).initializeSpaceUsed(spaceUsed); 800 } 801 802 void IDBServer::requestSpace(const ClientOrigin& origin, uint64_t taskSize, CompletionHandler<void(StorageQuotaManager::Decision)>&& callback) 803 { 804 auto* quotaManager = ensureQuotaUser(origin).manager(); 805 if (!quotaManager) { 806 callback(StorageQuotaManager::Decision::Deny); 807 return; 808 } 809 810 quotaManager->requestSpace(taskSize, WTFMove(callback)); 811 } 812 813 void IDBServer::resetSpaceUsed(const ClientOrigin& origin) 814 { 815 if (auto* user = m_quotaUsers.get(origin)) 816 user->resetSpaceUsed(); 817 } 818 819 void IDBServer::increaseSpaceUsed(const ClientOrigin& origin, uint64_t size) 820 { 821 ensureQuotaUser(origin).increaseSpaceUsed(size); 822 } 823 824 void IDBServer::decreaseSpaceUsed(const ClientOrigin& origin, uint64_t size) 825 { 826 ensureQuotaUser(origin).decreaseSpaceUsed(size); 827 } 828 829 void IDBServer::increasePotentialSpaceUsed(const ClientOrigin& origin, uint64_t taskSize) 830 { 831 ensureQuotaUser(origin).increasePotentialSpaceUsed(taskSize); 832 } 833 834 void IDBServer::decreasePotentialSpaceUsed(const ClientOrigin& origin, uint64_t spaceUsed) 835 { 836 ensureQuotaUser(origin).decreasePotentialSpaceUsed(spaceUsed); 704 837 } 705 838 -
trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h
r252805 r252839 31 31 #include "IDBDatabaseIdentifier.h" 32 32 #include "StorageQuotaManager.h" 33 #include "StorageQuotaUser.h" 33 34 #include "UniqueIDBDatabase.h" 34 35 #include "UniqueIDBDatabaseConnection.h" … … 58 59 class IDBServer : public RefCounted<IDBServer>, public CrossThreadTaskHandler, public CanMakeWeakPtr<IDBServer> { 59 60 public: 60 using StorageQuotaManagerSpaceRequester = Function<StorageQuotaManager::Decision(const ClientOrigin&, uint64_t spaceRequested)>;61 static Ref<IDBServer> create(PAL::SessionID, StorageQuotaManagerSpaceRequester&&);62 WEBCORE_EXPORT static Ref<IDBServer> create(PAL::SessionID, const String& databaseDirectoryPath, StorageQuotaManagerSpaceRequester&&);61 using QuotaManagerGetter = WTF::Function<StorageQuotaManager*(PAL::SessionID, const ClientOrigin&)>; 62 static Ref<IDBServer> create(PAL::SessionID, QuotaManagerGetter&&); 63 WEBCORE_EXPORT static Ref<IDBServer> create(PAL::SessionID, const String& databaseDirectoryPath, QuotaManagerGetter&&); 63 64 64 65 WEBCORE_EXPORT void registerConnection(IDBConnectionToClient&); … … 111 112 WEBCORE_EXPORT void closeAndDeleteDatabasesForOrigins(const Vector<SecurityOriginData>&, Function<void ()>&& completionHandler); 112 113 113 StorageQuotaManager::Decision requestSpace(const ClientOrigin&, uint64_t taskSize); 114 WEBCORE_EXPORT static uint64_t diskUsage(const String& rootDirectory, const ClientOrigin&); 114 void requestSpace(const ClientOrigin&, uint64_t taskSize, CompletionHandler<void(StorageQuotaManager::Decision)>&&); 115 void increasePotentialSpaceUsed(const ClientOrigin&, uint64_t taskSize); 116 void decreasePotentialSpaceUsed(const ClientOrigin&, uint64_t taskSize); 117 void increaseSpaceUsed(const ClientOrigin&, uint64_t size); 118 void decreaseSpaceUsed(const ClientOrigin&, uint64_t size); 119 void resetSpaceUsed(const ClientOrigin&); 120 121 void initializeQuotaUser(const ClientOrigin& origin) { ensureQuotaUser(origin); } 115 122 116 123 WEBCORE_EXPORT void tryStop(ShouldForceStop); … … 121 128 122 129 private: 123 IDBServer(PAL::SessionID, StorageQuotaManagerSpaceRequester&&);124 IDBServer(PAL::SessionID, const String& databaseDirectoryPath, StorageQuotaManagerSpaceRequester&&);130 IDBServer(PAL::SessionID, QuotaManagerGetter&&); 131 IDBServer(PAL::SessionID, const String& databaseDirectoryPath, QuotaManagerGetter&&); 125 132 126 133 UniqueIDBDatabase& getOrCreateUniqueIDBDatabase(const IDBDatabaseIdentifier&); … … 138 145 void removeDatabasesModifiedSinceForVersion(WallTime, const String&); 139 146 void removeDatabasesWithOriginsForVersion(const Vector<SecurityOriginData>&, const String&); 147 148 class QuotaUser final : public StorageQuotaUser { 149 WTF_MAKE_FAST_ALLOCATED; 150 public: 151 QuotaUser(IDBServer&, StorageQuotaManager*, ClientOrigin&&); 152 ~QuotaUser(); 153 154 StorageQuotaManager* manager() { return m_manager.get(); } 155 156 void setSpaceUsed(uint64_t spaceUsed) { m_spaceUsed = spaceUsed; } 157 void resetSpaceUsed(); 158 159 void increasePotentialSpaceUsed(uint64_t increase) { m_estimatedSpaceIncrease += increase; } 160 void decreasePotentialSpaceUsed(uint64_t decrease) 161 { 162 ASSERT(m_estimatedSpaceIncrease >= decrease); 163 m_estimatedSpaceIncrease -= decrease; 164 } 165 void increaseSpaceUsed(uint64_t size); 166 void decreaseSpaceUsed(uint64_t size); 167 168 void initializeSpaceUsed(uint64_t spaceUsed); 169 170 private: 171 uint64_t spaceUsed() const final 172 { 173 ASSERT(m_isInitialized); 174 return m_spaceUsed + m_estimatedSpaceIncrease; 175 } 176 void computeSpaceUsed() final; 177 void whenInitialized(CompletionHandler<void()>&&) final; 178 179 IDBServer& m_server; 180 WeakPtr<StorageQuotaManager> m_manager; 181 ClientOrigin m_origin; 182 bool m_isInitialized { false }; 183 uint64_t m_spaceUsed { 0 }; 184 uint64_t m_estimatedSpaceIncrease { 0 }; 185 CompletionHandler<void()> m_initializationCallback; 186 }; 187 188 WEBCORE_EXPORT QuotaUser& ensureQuotaUser(const ClientOrigin&); 189 void startComputingSpaceUsedForOrigin(const ClientOrigin&); 190 void computeSpaceUsedForOrigin(const ClientOrigin&); 191 void finishComputingSpaceUsedForOrigin(const ClientOrigin&, uint64_t spaceUsed); 140 192 141 193 PAL::SessionID m_sessionID; … … 151 203 String m_databaseDirectoryPath; 152 204 153 StorageQuotaManagerSpaceRequester m_spaceRequester; 205 HashMap<ClientOrigin, std::unique_ptr<QuotaUser>> m_quotaUsers; 206 QuotaManagerGetter m_quotaManagerGetter; 154 207 }; 155 208 -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.cpp
r252805 r252839 190 190 } 191 191 192 void UniqueIDBDatabase::requestSpace(UniqueIDBDatabaseTransaction& transaction, uint64_t taskSize, const char* taskName, CompletionHandler<void(IDBError&&)>&& callback) 193 { 194 m_server->requestSpace(m_identifier.origin(), taskSize, [weakThis = makeWeakPtr(this), this, weakTransaction = makeWeakPtr(transaction), taskName, callback = WTFMove(callback)](auto decision) mutable { 195 if (!weakThis) { 196 callback(IDBError { UnknownError }); 197 return; 198 } 199 200 if (!weakTransaction) { 201 callback(IDBError { UnknownError }); 202 return; 203 } 204 if (m_owningPointerForClose) { 205 // We are closing the database, there is no point in trying to modify the database at that point. 206 callback(IDBError { UnknownError }); 207 return; 208 } 209 210 switch (decision) { 211 case StorageQuotaManager::Decision::Deny: 212 callback(IDBError { QuotaExceededError, quotaErrorMessageName(taskName) }); 213 return; 214 case StorageQuotaManager::Decision::Grant: 215 callback(IDBError { }); 216 }; 217 }); 218 } 219 220 void UniqueIDBDatabase::waitForRequestSpaceCompletion(UniqueIDBDatabaseTransaction& transaction, CompletionHandler<void(IDBError&&)>&& callback) 221 { 222 requestSpace(transaction, 0, "", WTFMove(callback)); 223 } 224 225 void UniqueIDBDatabase::startSpaceIncreaseTask(uint64_t identifier, uint64_t taskSize) 226 { 227 m_server->increasePotentialSpaceUsed(m_identifier.origin(), taskSize); 228 ASSERT(!m_pendingSpaceIncreaseTasks.contains(identifier)); 229 m_pendingSpaceIncreaseTasks.add(identifier, taskSize); 230 } 231 232 void UniqueIDBDatabase::finishSpaceIncreaseTask(uint64_t identifier, bool isTaskSuccessful) 233 { 234 auto iterator = m_pendingSpaceIncreaseTasks.find(identifier); 235 ASSERT(iterator != m_pendingSpaceIncreaseTasks.end()); 236 m_server->decreasePotentialSpaceUsed(m_identifier.origin(), iterator->value); 237 if (isTaskSuccessful) 238 m_server->increaseSpaceUsed(m_identifier.origin(), iterator->value); 239 m_pendingSpaceIncreaseTasks.remove(iterator); 240 } 241 192 242 void UniqueIDBDatabase::performCurrentOpenOperation() 193 243 { … … 200 250 if (!m_isOpeningBackingStore) { 201 251 m_isOpeningBackingStore = true; 202 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::openBackingStore, m_identifier)); 252 // We do not know whether this is an existing or a new database. 253 // We set a small cost so that it is not possible to open an infinite number of database. 254 m_server->requestSpace(m_identifier.origin(), defaultWriteOperationCost, [this, weakThis = makeWeakPtr(this)](auto decision) mutable { 255 if (!weakThis) 256 return; 257 258 if (m_owningPointerForClose) 259 return; 260 261 switch (decision) { 262 case StorageQuotaManager::Decision::Deny: { 263 auto result = IDBResultData::error(m_currentOpenDBRequest->requestData().requestIdentifier(), IDBError { QuotaExceededError, quotaErrorMessageName("openDatabase") }); 264 m_currentOpenDBRequest->connection().didOpenDatabase(result); 265 m_currentOpenDBRequest = nullptr; 266 m_isOpeningBackingStore = false; 267 break; 268 } 269 case StorageQuotaManager::Decision::Grant: 270 auto callbackID = this->generateUniqueCallbackIdentifier(); 271 startSpaceIncreaseTask(callbackID, defaultWriteOperationCost); 272 this->postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::openBackingStore, m_identifier, callbackID)); 273 }; 274 }); 203 275 } 204 276 return; … … 764 836 } 765 837 766 void UniqueIDBDatabase::openBackingStore(const IDBDatabaseIdentifier& identifier )838 void UniqueIDBDatabase::openBackingStore(const IDBDatabaseIdentifier& identifier, uint64_t taskIdentifier) 767 839 { 768 840 ASSERT(!isMainThread()); 769 841 LOG(IndexedDB, "(db) UniqueIDBDatabase::openBackingStore (%p)", this); 770 842 843 ASSERT(!m_backingStore); 844 771 845 IDBDatabaseInfo databaseInfo; 772 m_origin = identifier.origin();773 // Quota check.774 auto decision = m_server->requestSpace(m_origin, defaultWriteOperationCost);775 if (decision == StorageQuotaManager::Decision::Deny) {776 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo, IDBError(QuotaExceededError, quotaErrorMessageName("OpenBackingStore"))));777 return;778 }779 780 ASSERT(!m_backingStore);781 846 IDBError error; 782 847 { … … 788 853 } 789 854 790 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo, error ));791 } 792 793 void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info, const IDBError& error )855 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didOpenBackingStore, databaseInfo, error, taskIdentifier)); 856 } 857 858 void UniqueIDBDatabase::didOpenBackingStore(const IDBDatabaseInfo& info, const IDBError& error, uint64_t taskIdentifier) 794 859 { 795 860 ASSERT(isMainThread()); … … 802 867 m_isOpeningBackingStore = false; 803 868 869 finishSpaceIncreaseTask(taskIdentifier, error.isNull()); 870 804 871 if (m_hardClosedForUserDelete) 805 872 return; … … 813 880 LOG(IndexedDB, "(main) UniqueIDBDatabase::createObjectStore"); 814 881 882 auto taskSize = defaultWriteOperationCost + estimateSize(info); 883 requestSpace(transaction, taskSize, "createObjectStore", [this, taskSize, &transaction, info, callback = WTFMove(callback)](auto error) mutable { 884 if (!error.isNull() && *error.code() != QuotaExceededError) { 885 callback(WTFMove(error)); 886 return; 887 } 888 this->createObjectStoreAfterQuotaCheck(taskSize, transaction, info, WTFMove(callback), error); 889 }); 890 } 891 892 void UniqueIDBDatabase::createObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, const IDBObjectStoreInfo& info, ErrorCallback callback, const IDBError& quotaError) 893 { 815 894 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 816 895 if (!callbackID) 817 896 return; 818 897 819 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info)); 820 } 821 822 void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info) 898 startSpaceIncreaseTask(callbackID, taskSize); 899 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateObjectStore, callbackID, transaction.info().identifier(), info, quotaError)); 900 } 901 902 void UniqueIDBDatabase::performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& info, const IDBError& quotaError) 823 903 { 824 904 ASSERT(!isMainThread()); 825 905 LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateObjectStore"); 826 906 827 // Quota check. 828 auto taskSize = defaultWriteOperationCost + estimateSize(info); 829 if (m_server->requestSpace(m_origin, taskSize) == StorageQuotaManager::Decision::Deny) { 830 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateObjectStore, callbackIdentifier, IDBError(QuotaExceededError, quotaErrorMessageName("CreateObjectStore")), info)); 907 if (!quotaError.isNull()) { 908 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateObjectStore, callbackIdentifier, quotaError, info)); 831 909 return; 832 910 } … … 847 925 LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCreateObjectStore"); 848 926 927 finishSpaceIncreaseTask(callbackIdentifier, error.isNull()); 849 928 if (error.isNull()) 850 929 m_databaseInfo->addExistingObjectStore(info); … … 858 937 LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteObjectStore"); 859 938 939 waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreName, callback = WTFMove(callback)](auto&& error) mutable { 940 if (!error.isNull()) { 941 callback(WTFMove(error)); 942 return; 943 } 944 this->deleteObjectStoreAfterQuotaCheck(transaction, objectStoreName, WTFMove(callback)); 945 }); 946 } 947 948 void UniqueIDBDatabase::deleteObjectStoreAfterQuotaCheck(UniqueIDBDatabaseTransaction& transaction, const String& objectStoreName, ErrorCallback callback) 949 { 860 950 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 861 951 if (!callbackID) … … 902 992 LOG(IndexedDB, "(main) UniqueIDBDatabase::renameObjectStore"); 903 993 994 auto taskSize = defaultWriteOperationCost + newName.sizeInBytes(); 995 requestSpace(transaction, taskSize, "renameObjectStore", [this, taskSize, &transaction, objectStoreIdentifier, newName, callback = WTFMove(callback)](auto error) mutable { 996 if (!error.isNull() && *error.code() != QuotaExceededError) { 997 callback(WTFMove(error)); 998 return; 999 } 1000 this->renameObjectStoreAfterQuotaCheck(taskSize, transaction, objectStoreIdentifier, newName, WTFMove(callback), error); 1001 }); 1002 } 1003 1004 void UniqueIDBDatabase::renameObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback callback, const IDBError& quotaError) 1005 { 904 1006 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 905 1007 if (!callbackID) 906 1008 return; 907 1009 908 IDBError error ;1010 IDBError error = quotaError; 909 1011 auto* info = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier); 910 1012 if (!info) 911 1013 error = IDBError { UnknownError, "Attempt to rename non-existant object store"_s }; 912 1014 1015 startSpaceIncreaseTask(callbackID, taskSize); 913 1016 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameObjectStore, callbackID, transaction.info().identifier(), objectStoreIdentifier, newName, error)); 914 1017 } … … 919 1022 LOG(IndexedDB, "(db) UniqueIDBDatabase::performRenameObjectStore"); 920 1023 921 // Quota check. 922 auto taskSize = defaultWriteOperationCost + newName.sizeInBytes(); 923 if (m_server->requestSpace(m_origin, taskSize) == StorageQuotaManager::Decision::Deny) { 924 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameObjectStore, callbackIdentifier, IDBError(QuotaExceededError, quotaErrorMessageName("RenameObjectStore")), objectStoreIdentifier, newName)); 1024 if (!error.isNull()) { 1025 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameObjectStore, callbackIdentifier, error, objectStoreIdentifier, newName)); 925 1026 return; 926 1027 } … … 940 1041 LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformRenameObjectStore"); 941 1042 1043 finishSpaceIncreaseTask(callbackIdentifier, error.isNull()); 942 1044 if (error.isNull()) 943 1045 m_databaseInfo->renameObjectStore(objectStoreIdentifier, newName); … … 951 1053 LOG(IndexedDB, "(main) UniqueIDBDatabase::clearObjectStore"); 952 1054 1055 waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreIdentifier, callback = WTFMove(callback)](auto&& error) mutable { 1056 if (!error.isNull()) { 1057 callback(WTFMove(error)); 1058 return; 1059 } 1060 this->clearObjectStoreAfetQuotaCheck(transaction, objectStoreIdentifier, WTFMove(callback)); 1061 }); 1062 } 1063 1064 void UniqueIDBDatabase::clearObjectStoreAfetQuotaCheck(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, ErrorCallback callback) 1065 { 953 1066 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 954 1067 if (!callbackID) … … 985 1098 LOG(IndexedDB, "(main) UniqueIDBDatabase::createIndex"); 986 1099 1100 auto taskSize = defaultWriteOperationCost + estimateSize(info); 1101 requestSpace(transaction, taskSize, "createIndex", [this, taskSize, &transaction, info, callback = WTFMove(callback)](auto error) mutable { 1102 if (!error.isNull() && *error.code() != QuotaExceededError) { 1103 callback(WTFMove(error)); 1104 return; 1105 } 1106 this->createIndexAfterQuotaCheck(taskSize, transaction, info, WTFMove(callback), error); 1107 }); 1108 } 1109 1110 void UniqueIDBDatabase::createIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, const IDBIndexInfo& info, ErrorCallback callback, const IDBError& quotaError) 1111 { 987 1112 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 988 1113 if (!callbackID) 989 1114 return; 990 1115 991 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info)); 992 } 993 994 void UniqueIDBDatabase::performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info) 1116 startSpaceIncreaseTask(callbackID, taskSize); 1117 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performCreateIndex, callbackID, transaction.info().identifier(), info, quotaError)); 1118 } 1119 1120 void UniqueIDBDatabase::performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& info, const IDBError& quotaError) 995 1121 { 996 1122 ASSERT(!isMainThread()); 997 1123 LOG(IndexedDB, "(db) UniqueIDBDatabase::performCreateIndex"); 998 1124 999 auto taskSize = defaultWriteOperationCost + estimateSize(info); 1000 if (m_server->requestSpace(m_origin, taskSize) == StorageQuotaManager::Decision::Deny) { 1001 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateIndex, callbackIdentifier, IDBError(QuotaExceededError, quotaErrorMessageName("CreateIndex")), info)); 1125 if (!quotaError.isNull()) { 1126 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformCreateIndex, callbackIdentifier, quotaError, info)); 1002 1127 return; 1003 1128 } … … 1024 1149 LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformCreateIndex"); 1025 1150 1151 finishSpaceIncreaseTask(callbackIdentifier, error.isNull()); 1152 1026 1153 if (error.isNull()) { 1027 1154 ASSERT(m_databaseInfo); … … 1039 1166 LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteIndex"); 1040 1167 1168 waitForRequestSpaceCompletion(transaction, [this, &transaction, objectStoreIdentifier, indexName, callback = WTFMove(callback)](auto&& error) mutable { 1169 if (!error.isNull()) { 1170 callback(WTFMove(error)); 1171 return; 1172 } 1173 this->deleteIndexAfterQuotaCheck(transaction, objectStoreIdentifier, indexName, WTFMove(callback)); 1174 }); 1175 } 1176 1177 void UniqueIDBDatabase::deleteIndexAfterQuotaCheck(UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, const String& indexName, ErrorCallback callback) 1178 { 1041 1179 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1042 1180 if (!callbackID) … … 1092 1230 LOG(IndexedDB, "(main) UniqueIDBDatabase::renameIndex"); 1093 1231 1232 auto taskSize = defaultWriteOperationCost + newName.sizeInBytes(); 1233 requestSpace(transaction, taskSize, "renameIndex", [this, taskSize, &transaction, objectStoreIdentifier, indexIdentifier, newName, callback = WTFMove(callback)](auto error) mutable { 1234 if (!error.isNull() && *error.code() != QuotaExceededError) { 1235 callback(WTFMove(error)); 1236 return; 1237 } 1238 this->renameIndexAfterQuotaCheck(taskSize, transaction, objectStoreIdentifier, indexIdentifier, newName, WTFMove(callback), error); 1239 }); 1240 } 1241 1242 void UniqueIDBDatabase::renameIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction& transaction, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback callback, const IDBError& quotaError) 1243 { 1094 1244 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1095 1245 if (!callbackID) 1096 1246 return; 1097 1247 1098 IDBError error ;1248 IDBError error = quotaError; 1099 1249 auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier); 1100 1250 if (!objectStoreInfo) … … 1105 1255 error = IDBError { UnknownError, "Attempt to rename non-existant index"_s }; 1106 1256 1257 startSpaceIncreaseTask(callbackID, taskSize); 1107 1258 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performRenameIndex, callbackID, transaction.info().identifier(), objectStoreIdentifier, indexIdentifier, newName, error)); 1108 1259 } … … 1113 1264 LOG(IndexedDB, "(db) UniqueIDBDatabase::performRenameIndex"); 1114 1265 1115 // Quota check. 1116 auto taskSize = defaultWriteOperationCost + newName.sizeInBytes(); 1117 if (m_server->requestSpace(m_origin, taskSize) == StorageQuotaManager::Decision::Deny) { 1118 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameIndex, callbackIdentifier, IDBError(QuotaExceededError, quotaErrorMessageName("RenameIndex")), objectStoreIdentifier, indexIdentifier, newName)); 1266 if (!error.isNull()) { 1267 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformRenameIndex, callbackIdentifier, error, objectStoreIdentifier, indexIdentifier, newName)); 1119 1268 return; 1120 1269 } … … 1134 1283 LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformRenameIndex"); 1135 1284 1285 finishSpaceIncreaseTask(callbackIdentifier, error.isNull()); 1136 1286 if (error.isNull()) { 1137 1287 auto* objectStoreInfo = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier); … … 1147 1297 } 1148 1298 1149 void UniqueIDBDatabase::putOrAdd( const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback)1299 void UniqueIDBDatabase::putOrAdd(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback) 1150 1300 { 1151 1301 ASSERT(isMainThread()); 1152 1302 LOG(IndexedDB, "(main) UniqueIDBDatabase::putOrAdd"); 1153 1303 1304 auto taskSize = defaultWriteOperationCost + estimateSize(keyData) + estimateSize(value); 1305 ASSERT(m_databaseInfo); 1306 auto* objectStore = m_databaseInfo->infoForExistingObjectStore(requestData.objectStoreIdentifier()); 1307 if (objectStore) 1308 taskSize += objectStore->indexNames().size() * taskSize; 1309 1310 requestSpace(transaction, taskSize, "putOrAdd", [this, taskSize, requestData, keyData, value, callback = WTFMove(callback), overwriteMode](auto error) mutable { 1311 if (!error.isNull() && *error.code() != QuotaExceededError) { 1312 callback(WTFMove(error), { }); 1313 return; 1314 } 1315 this->putOrAddAfterQuotaCheck(taskSize, requestData, keyData, value, overwriteMode, WTFMove(callback), error); 1316 }); 1317 } 1318 1319 void UniqueIDBDatabase::putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequestData& requestData, const IDBKeyData& keyData, const IDBValue& value, IndexedDB::ObjectStoreOverwriteMode overwriteMode, KeyDataCallback callback, const IDBError& quotaError) 1320 { 1154 1321 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1155 1322 if (!callbackID) 1156 1323 return; 1157 1324 1158 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode)); 1159 } 1160 1161 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode) 1325 startSpaceIncreaseTask(callbackID, taskSize); 1326 postDatabaseTask(createCrossThreadTask(*this, &UniqueIDBDatabase::performPutOrAdd, callbackID, requestData.transactionIdentifier(), requestData.objectStoreIdentifier(), keyData, value, overwriteMode, quotaError)); 1327 } 1328 1329 void UniqueIDBDatabase::performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData& keyData, const IDBValue& originalRecordValue, IndexedDB::ObjectStoreOverwriteMode overwriteMode, const IDBError& quotaError) 1162 1330 { 1163 1331 ASSERT(!isMainThread()); 1164 1332 LOG(IndexedDB, "(db) UniqueIDBDatabase::performPutOrAdd"); 1165 1333 1334 ASSERT(m_backingStore); 1335 ASSERT(objectStoreIdentifier); 1336 1166 1337 IDBKeyData usedKey; 1167 1338 IDBError error; 1168 1339 1169 // Quota check. 1170 auto taskSize = defaultWriteOperationCost + estimateSize(keyData) + estimateSize(originalRecordValue); 1171 ASSERT(m_databaseInfo); 1172 auto* objectStore = m_databaseInfo->infoForExistingObjectStore(objectStoreIdentifier); 1173 if (objectStore) 1174 taskSize += objectStore->indexNames().size() * taskSize; 1175 if (m_server->requestSpace(m_origin, taskSize) == StorageQuotaManager::Decision::Deny) { 1176 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, IDBError(QuotaExceededError, quotaErrorMessageName("PutOrAdd")), usedKey)); 1177 return; 1178 } 1179 1180 ASSERT(m_backingStore); 1181 ASSERT(objectStoreIdentifier); 1340 if (!quotaError.isNull()) { 1341 postDatabaseTaskReply(createCrossThreadTask(*this, &UniqueIDBDatabase::didPerformPutOrAdd, callbackIdentifier, quotaError, usedKey)); 1342 return; 1343 } 1344 1182 1345 { 1183 1346 LockHolder locker(m_backingStoreLock); … … 1256 1419 LOG(IndexedDB, "(main) UniqueIDBDatabase::didPerformPutOrAdd"); 1257 1420 1421 finishSpaceIncreaseTask(callbackIdentifier, error.isNull()); 1258 1422 performKeyDataCallback(callbackIdentifier, error, resultKey); 1259 1423 } 1260 1424 1261 void UniqueIDBDatabase::getRecord( const IDBRequestData& requestData, const IDBGetRecordData& getRecordData, GetResultCallback callback)1425 void UniqueIDBDatabase::getRecord(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBGetRecordData& getRecordData, GetResultCallback callback) 1262 1426 { 1263 1427 ASSERT(isMainThread()); 1264 1428 LOG(IndexedDB, "(main) UniqueIDBDatabase::getRecord"); 1265 1429 1430 waitForRequestSpaceCompletion(transaction, [this, requestData, getRecordData, callback = WTFMove(callback)](auto&& error) mutable { 1431 if (!error.isNull()) { 1432 callback(WTFMove(error), { }); 1433 return; 1434 } 1435 this->getRecordAfterQuotaCheck(requestData, getRecordData, WTFMove(callback)); 1436 }); 1437 } 1438 1439 void UniqueIDBDatabase::getRecordAfterQuotaCheck(const IDBRequestData& requestData, const IDBGetRecordData& getRecordData, GetResultCallback callback) 1440 { 1266 1441 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1267 1442 if (!callbackID) … … 1274 1449 } 1275 1450 1276 void UniqueIDBDatabase::getAllRecords( const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData, GetAllResultsCallback callback)1451 void UniqueIDBDatabase::getAllRecords(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData, GetAllResultsCallback callback) 1277 1452 { 1278 1453 ASSERT(isMainThread()); 1279 1454 LOG(IndexedDB, "(main) UniqueIDBDatabase::getAllRecords"); 1280 1455 1456 waitForRequestSpaceCompletion(transaction, [this, requestData, getAllRecordsData, callback = WTFMove(callback)](auto&& error) mutable { 1457 if (!error.isNull()) { 1458 callback(WTFMove(error), { }); 1459 return; 1460 } 1461 this->getAllRecordsAfterQuotaCheck(requestData, getAllRecordsData, WTFMove(callback)); 1462 }); 1463 } 1464 1465 void UniqueIDBDatabase::getAllRecordsAfterQuotaCheck(const IDBRequestData& requestData, const IDBGetAllRecordsData& getAllRecordsData, GetAllResultsCallback callback) 1466 { 1281 1467 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1282 1468 if (!callbackID) … … 1292 1478 1293 1479 ASSERT(m_backingStore); 1480 1294 1481 IDBGetResult result; 1295 1482 IDBError error; … … 1332 1519 1333 1520 ASSERT(m_backingStore); 1521 1334 1522 IDBGetAllResult result; 1335 1523 IDBError error; … … 1350 1538 } 1351 1539 1352 void UniqueIDBDatabase::getCount( const IDBRequestData& requestData, const IDBKeyRangeData& range, CountCallback callback)1540 void UniqueIDBDatabase::getCount(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBKeyRangeData& range, CountCallback callback) 1353 1541 { 1354 1542 ASSERT(isMainThread()); 1355 1543 LOG(IndexedDB, "(main) UniqueIDBDatabase::getCount"); 1356 1544 1545 waitForRequestSpaceCompletion(transaction, [this, requestData, range, callback = WTFMove(callback)](auto&& error) mutable { 1546 if (!error.isNull()) { 1547 callback(WTFMove(error), { }); 1548 return; 1549 } 1550 this->getCountAfterQuotaCheck(requestData, range, WTFMove(callback)); 1551 }); 1552 } 1553 1554 void UniqueIDBDatabase::getCountAfterQuotaCheck(const IDBRequestData& requestData, const IDBKeyRangeData& range, CountCallback callback) 1555 { 1357 1556 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1358 1557 if (!callbackID) … … 1387 1586 } 1388 1587 1389 void UniqueIDBDatabase::deleteRecord( const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData, ErrorCallback callback)1588 void UniqueIDBDatabase::deleteRecord(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData, ErrorCallback callback) 1390 1589 { 1391 1590 ASSERT(isMainThread()); 1392 1591 LOG(IndexedDB, "(main) UniqueIDBDatabase::deleteRecord"); 1393 1592 1593 waitForRequestSpaceCompletion(transaction, [this, requestData, keyRangeData, callback = WTFMove(callback)](auto&& error) mutable { 1594 if (!error.isNull()) { 1595 callback(WTFMove(error)); 1596 return; 1597 } 1598 this->deleteRecordAfterQuotaCheck(requestData, keyRangeData, WTFMove(callback)); 1599 }); 1600 } 1601 1602 void UniqueIDBDatabase::deleteRecordAfterQuotaCheck(const IDBRequestData& requestData, const IDBKeyRangeData& keyRangeData, ErrorCallback callback) 1603 { 1394 1604 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1395 1605 if (!callbackID) … … 1420 1630 } 1421 1631 1422 void UniqueIDBDatabase::openCursor( const IDBRequestData& requestData, const IDBCursorInfo& info, GetResultCallback callback)1632 void UniqueIDBDatabase::openCursor(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBCursorInfo& info, GetResultCallback callback) 1423 1633 { 1424 1634 ASSERT(isMainThread()); 1425 1635 LOG(IndexedDB, "(main) UniqueIDBDatabase::openCursor"); 1426 1636 1637 waitForRequestSpaceCompletion(transaction, [this, requestData, info, callback = WTFMove(callback)](auto&& error) mutable { 1638 if (!error.isNull()) { 1639 callback(WTFMove(error), { }); 1640 return; 1641 } 1642 this->openCursorAfterQuotaCheck(requestData, info, WTFMove(callback)); 1643 }); 1644 } 1645 1646 void UniqueIDBDatabase::openCursorAfterQuotaCheck(const IDBRequestData& requestData, const IDBCursorInfo& info, GetResultCallback callback) 1647 { 1427 1648 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1428 1649 if (!callbackID) … … 1454 1675 } 1455 1676 1456 void UniqueIDBDatabase::iterateCursor( const IDBRequestData& requestData, const IDBIterateCursorData& data, GetResultCallback callback)1677 void UniqueIDBDatabase::iterateCursor(UniqueIDBDatabaseTransaction& transaction, const IDBRequestData& requestData, const IDBIterateCursorData& data, GetResultCallback callback) 1457 1678 { 1458 1679 ASSERT(isMainThread()); 1459 1680 LOG(IndexedDB, "(main) UniqueIDBDatabase::iterateCursor"); 1460 1681 1682 waitForRequestSpaceCompletion(transaction, [this, requestData, data, callback = WTFMove(callback)](auto&& error) mutable { 1683 if (!error.isNull()) { 1684 callback(WTFMove(error), { }); 1685 return; 1686 } 1687 this->iterateCursorAfterQuotaCheck(requestData, data, WTFMove(callback)); 1688 }); 1689 } 1690 1691 void UniqueIDBDatabase::iterateCursorAfterQuotaCheck(const IDBRequestData& requestData, const IDBIterateCursorData& data, GetResultCallback callback) 1692 { 1461 1693 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1462 1694 if (!callbackID) … … 1536 1768 ASSERT(transaction.databaseConnection().database() == this); 1537 1769 1770 waitForRequestSpaceCompletion(transaction, [this, &transaction, callback = WTFMove(callback)](auto&& error) mutable { 1771 if (!error.isNull()) { 1772 callback(WTFMove(error)); 1773 return; 1774 } 1775 this->commitTransactionAfterQuotaCheck(transaction, WTFMove(callback)); 1776 }); 1777 } 1778 1779 void UniqueIDBDatabase::commitTransactionAfterQuotaCheck(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback) 1780 { 1538 1781 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); 1539 1782 if (!callbackID) … … 1593 1836 } 1594 1837 1595 void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, ErrorCallback callback)1838 void UniqueIDBDatabase::abortTransaction(UniqueIDBDatabaseTransaction& transaction, WaitForPendingTasks waitForPendingTasks, ErrorCallback callback) 1596 1839 { 1597 1840 ASSERT(isMainThread()); … … 1599 1842 1600 1843 ASSERT(transaction.databaseConnection().database() == this); 1844 1845 if (waitForPendingTasks == WaitForPendingTasks::Yes) { 1846 waitForRequestSpaceCompletion(transaction, [this, &transaction, callback = WTFMove(callback)](auto&& error) mutable { 1847 if (!error.isNull()) { 1848 callback(WTFMove(error)); 1849 return; 1850 } 1851 this->abortTransaction(transaction, WaitForPendingTasks::No, WTFMove(callback)); 1852 }); 1853 return; 1854 } 1601 1855 1602 1856 uint64_t callbackID = storeCallbackOrFireError(WTFMove(callback)); -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabase.h
r252805 r252839 45 45 namespace WebCore { 46 46 47 struct ClientOrigin;48 47 class IDBError; 49 48 class IDBGetAllResult; … … 91 90 void deleteIndex(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String& indexName, ErrorCallback); 92 91 void renameIndex(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback); 93 void putOrAdd( const IDBRequestData&, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback);94 void getRecord( const IDBRequestData&, const IDBGetRecordData&, GetResultCallback);95 void getAllRecords( const IDBRequestData&, const IDBGetAllRecordsData&, GetAllResultsCallback);96 void getCount( const IDBRequestData&, const IDBKeyRangeData&, CountCallback);97 void deleteRecord( const IDBRequestData&, const IDBKeyRangeData&, ErrorCallback);98 void openCursor( const IDBRequestData&, const IDBCursorInfo&, GetResultCallback);99 void iterateCursor( const IDBRequestData&, const IDBIterateCursorData&, GetResultCallback);92 void putOrAdd(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback); 93 void getRecord(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBGetRecordData&, GetResultCallback); 94 void getAllRecords(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBGetAllRecordsData&, GetAllResultsCallback); 95 void getCount(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBKeyRangeData&, CountCallback); 96 void deleteRecord(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBKeyRangeData&, ErrorCallback); 97 void openCursor(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBCursorInfo&, GetResultCallback); 98 void iterateCursor(UniqueIDBDatabaseTransaction&, const IDBRequestData&, const IDBIterateCursorData&, GetResultCallback); 100 99 void commitTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback); 101 void abortTransaction(UniqueIDBDatabaseTransaction&, ErrorCallback); 100 101 enum class WaitForPendingTasks { No, Yes }; 102 void abortTransaction(UniqueIDBDatabaseTransaction&, WaitForPendingTasks, ErrorCallback); 102 103 103 104 void didFinishHandlingVersionChange(UniqueIDBDatabaseConnection&, const IDBResourceIdentifier& transactionIdentifier); … … 140 141 void scheduleShutdownForClose(); 141 142 143 void createObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, const IDBObjectStoreInfo&, ErrorCallback, const IDBError&); 144 void renameObjectStoreAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String& newName, ErrorCallback, const IDBError&); 145 void createIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, const IDBIndexInfo&, ErrorCallback, const IDBError&); 146 void renameIndexAfterQuotaCheck(uint64_t taskSize, UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, ErrorCallback, const IDBError&); 147 void putOrAddAfterQuotaCheck(uint64_t taskSize, const IDBRequestData&, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, KeyDataCallback, const IDBError&); 148 void deleteRecordAfterQuotaCheck(const IDBRequestData&, const IDBKeyRangeData&, ErrorCallback); 149 150 void deleteObjectStoreAfterQuotaCheck(UniqueIDBDatabaseTransaction&, const String& objectStoreName, ErrorCallback); 151 void clearObjectStoreAfetQuotaCheck(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, ErrorCallback); 152 void deleteIndexAfterQuotaCheck(UniqueIDBDatabaseTransaction&, uint64_t objectStoreIdentifier, const String&, ErrorCallback); 153 void getRecordAfterQuotaCheck(const IDBRequestData&, const IDBGetRecordData&, GetResultCallback); 154 void getAllRecordsAfterQuotaCheck(const IDBRequestData&, const IDBGetAllRecordsData&, GetAllResultsCallback); 155 void getCountAfterQuotaCheck(const IDBRequestData&, const IDBKeyRangeData&, CountCallback); 156 void openCursorAfterQuotaCheck(const IDBRequestData&, const IDBCursorInfo&, GetResultCallback); 157 void iterateCursorAfterQuotaCheck(const IDBRequestData&, const IDBIterateCursorData&, GetResultCallback); 158 void commitTransactionAfterQuotaCheck(UniqueIDBDatabaseTransaction&, ErrorCallback); 159 142 160 // Database thread operations 143 161 void deleteBackingStore(const IDBDatabaseIdentifier&); 144 void openBackingStore(const IDBDatabaseIdentifier& );162 void openBackingStore(const IDBDatabaseIdentifier&, uint64_t taskIdentifier); 145 163 void performCommitTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier); 146 164 void performAbortTransaction(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier); 147 165 void beginTransactionInBackingStore(const IDBTransactionInfo&); 148 void performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo& );166 void performCreateObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBObjectStoreInfo&, const IDBError&); 149 167 void performDeleteObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier); 150 168 void performRenameObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const String& newName, const IDBError&); 151 169 void performClearObjectStore(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier); 152 void performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo& );170 void performCreateIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBIndexInfo&, const IDBError&); 153 171 void performDeleteIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier); 154 172 void performRenameIndex(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, uint64_t indexIdentifier, const String& newName, const IDBError&); 155 void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode );173 void performPutOrAdd(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyData&, const IDBValue&, IndexedDB::ObjectStoreOverwriteMode, const IDBError&); 156 174 void performGetRecord(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, uint64_t objectStoreIdentifier, const IDBKeyRangeData&, IDBGetRecordDataType); 157 175 void performGetAllRecords(uint64_t callbackIdentifier, const IDBResourceIdentifier& transactionIdentifier, const IDBGetAllRecordsData&); … … 170 188 // Main thread callbacks 171 189 void didDeleteBackingStore(uint64_t deletedVersion); 172 void didOpenBackingStore(const IDBDatabaseInfo&, const IDBError& );190 void didOpenBackingStore(const IDBDatabaseInfo&, const IDBError&, uint64_t taskIdentifier); 173 191 void didPerformCreateObjectStore(uint64_t callbackIdentifier, const IDBError&, const IDBObjectStoreInfo&); 174 192 void didPerformDeleteObjectStore(uint64_t callbackIdentifier, const IDBError&, uint64_t objectStoreIdentifier); … … 229 247 bool isDoneWithHardClose(); 230 248 249 void requestSpace(UniqueIDBDatabaseTransaction&, uint64_t taskSize, const char* errorMessage, CompletionHandler<void(IDBError&&)>&&); 250 void waitForRequestSpaceCompletion(UniqueIDBDatabaseTransaction&, CompletionHandler<void(IDBError&&)>&&); 251 void startSpaceIncreaseTask(uint64_t identifier, uint64_t taskSize); 252 void finishSpaceIncreaseTask(uint64_t identifier, bool isTaskSuccessful); 253 231 254 void clearTransactionsOnConnection(UniqueIDBDatabaseConnection&); 232 255 … … 289 312 HashSet<IDBResourceIdentifier> m_cursorPrefetches; 290 313 314 HashMap<uint64_t, uint64_t> m_pendingSpaceIncreaseTasks; 315 291 316 bool m_isSuspended { false }; 292 293 ClientOrigin m_origin;294 317 }; 295 318 -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseConnection.cpp
r252805 r252839 77 77 return; 78 78 79 m_database->abortTransaction(transaction, [this, protectedThis, transactionIdentifier](const IDBError&) {79 m_database->abortTransaction(transaction, UniqueIDBDatabase::WaitForPendingTasks::No, [this, protectedThis, transactionIdentifier](const IDBError&) { 80 80 ASSERT(m_transactionMap.contains(transactionIdentifier)); 81 81 m_transactionMap.remove(transactionIdentifier); -
trunk/Source/WebCore/Modules/indexeddb/server/UniqueIDBDatabaseTransaction.cpp
r252805 r252839 80 80 ASSERT(database); 81 81 82 database->abortTransaction(*this, [this, weakThis = makeWeakPtr(*this)](auto& error) {82 database->abortTransaction(*this, UniqueIDBDatabase::WaitForPendingTasks::Yes, [this, weakThis = makeWeakPtr(*this)](auto& error) { 83 83 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::abort (callback)"); 84 84 if (!weakThis) … … 287 287 ASSERT(database); 288 288 289 database->putOrAdd( requestData, keyData, value, overwriteMode, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBKeyData& key) {289 database->putOrAdd(*this, requestData, keyData, value, overwriteMode, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBKeyData& key) { 290 290 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::putOrAdd (callback)"); 291 291 if (!weakThis) … … 308 308 ASSERT(database); 309 309 310 database->getRecord( requestData, getRecordData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetResult& result) {310 database->getRecord(*this, requestData, getRecordData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetResult& result) { 311 311 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getRecord (callback)"); 312 312 if (!weakThis) … … 329 329 ASSERT(database); 330 330 331 database->getAllRecords( requestData, getAllRecordsData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetAllResult& result) {331 database->getAllRecords(*this, requestData, getAllRecordsData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetAllResult& result) { 332 332 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getAllRecords (callback)"); 333 333 if (!weakThis) … … 350 350 ASSERT(database); 351 351 352 database->getCount( requestData, keyRangeData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, uint64_t count) {352 database->getCount(*this, requestData, keyRangeData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, uint64_t count) { 353 353 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::getCount (callback)"); 354 354 if (!weakThis) … … 371 371 ASSERT(database); 372 372 373 database->deleteRecord( requestData, keyRangeData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error) {373 database->deleteRecord(*this, requestData, keyRangeData, [this, weakThis = makeWeakPtr(*this), requestData](auto& error) { 374 374 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::deleteRecord (callback)"); 375 375 if (!weakThis) … … 392 392 ASSERT(database); 393 393 394 database->openCursor( requestData, info, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetResult& result) {394 database->openCursor(*this, requestData, info, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetResult& result) { 395 395 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::openCursor (callback)"); 396 396 if (!weakThis) … … 413 413 ASSERT(database); 414 414 415 database->iterateCursor( requestData, data, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetResult& result) {415 database->iterateCursor(*this, requestData, data, [this, weakThis = makeWeakPtr(*this), requestData](auto& error, const IDBGetResult& result) { 416 416 LOG(IndexedDB, "UniqueIDBDatabaseTransaction::iterateCursor (callback)"); 417 417 if (!weakThis) -
trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.cpp
r252805 r252839 65 65 { 66 66 return m_quotaManagers.ensure(origin, [] { 67 return StorageQuotaManager::create(StorageQuotaManager::defaultQuota(), [] { 68 return 0; 69 }, [](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) { 67 return makeUnique<StorageQuotaManager>(StorageQuotaManager::defaultQuota(), [](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) { 70 68 callback(quota + currentSpace + spaceIncrease); 71 69 }); … … 73 71 } 74 72 75 static inline IDBServer::IDBServer::StorageQuotaManagerSpaceRequester storageQuotaManagerSpaceRequester(InProcessIDBServer& server) 76 { 77 return [server = &server, weakServer = makeWeakPtr(server)](const ClientOrigin& origin, uint64_t spaceRequested) mutable { 78 auto* storageQuotaManager = weakServer ? server->quotaManager(origin) : nullptr; 79 return storageQuotaManager ? storageQuotaManager->requestSpaceOnBackgroundThread(spaceRequested) : StorageQuotaManager::Decision::Deny; 73 static inline IDBServer::IDBServer::QuotaManagerGetter storageQuotaManagerGetter(InProcessIDBServer& server) 74 { 75 return [weakServer = makeWeakPtr(server)](PAL::SessionID, const auto& origin) { 76 return weakServer ? weakServer->quotaManager(origin) : nullptr; 80 77 }; 81 78 } 82 79 83 80 InProcessIDBServer::InProcessIDBServer(PAL::SessionID sessionID) 84 : m_server(IDBServer::IDBServer::create(sessionID, storageQuotaManagerSpaceRequester(*this))) 85 { 86 ASSERT(isMainThread()); 81 : m_server(IDBServer::IDBServer::create(sessionID, storageQuotaManagerGetter(*this))) 82 { 87 83 relaxAdoptionRequirement(); 88 84 m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this); … … 91 87 92 88 InProcessIDBServer::InProcessIDBServer(PAL::SessionID sessionID, const String& databaseDirectoryPath) 93 : m_server(IDBServer::IDBServer::create(sessionID, databaseDirectoryPath, storageQuotaManagerSpaceRequester(*this))) 94 { 95 ASSERT(isMainThread()); 89 : m_server(IDBServer::IDBServer::create(sessionID, databaseDirectoryPath, storageQuotaManagerGetter(*this))) 90 { 96 91 relaxAdoptionRequirement(); 97 92 m_connectionToServer = IDBClient::IDBConnectionToServer::create(*this); -
trunk/Source/WebCore/Modules/indexeddb/shared/InProcessIDBServer.h
r252805 r252839 65 65 IDBServer::IDBConnectionToClient& connectionToClient() const; 66 66 IDBServer::IDBServer& server() { return m_server.get(); } 67 67 68 IDBServer::IDBServer& idbServer() { return m_server.get(); } 68 69 … … 135 136 RefPtr<IDBServer::IDBConnectionToClient> m_connectionToClient; 136 137 137 HashMap<ClientOrigin, RefPtr<StorageQuotaManager>> m_quotaManagers;138 HashMap<ClientOrigin, std::unique_ptr<StorageQuotaManager>> m_quotaManagers; 138 139 }; 139 140 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r252820 r252839 1130 1130 41D41C672256874F00697942 /* ServiceWorkerInternals.mm in Sources */ = {isa = PBXBuildFile; fileRef = 41D41C652256859200697942 /* ServiceWorkerInternals.mm */; }; 1131 1131 41DE7C7C222DA14300532B65 /* StorageQuotaManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DE7C7B222DA13E00532B65 /* StorageQuotaManager.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1132 41DE7C7D222DA14800532B65 /* StorageQuotaUser.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DE7C78222DA13C00532B65 /* StorageQuotaUser.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1132 1133 41DEFCB61E56C1BD000D9E5F /* JSDOMMapLike.h in Headers */ = {isa = PBXBuildFile; fileRef = 41DEFCB41E56C1B9000D9E5F /* JSDOMMapLike.h */; }; 1133 1134 41E1B1D10FF5986900576B3B /* AbstractWorker.h in Headers */ = {isa = PBXBuildFile; fileRef = 41E1B1CB0FF5986900576B3B /* AbstractWorker.h */; }; … … 7465 7466 41D41C652256859200697942 /* ServiceWorkerInternals.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ServiceWorkerInternals.mm; sourceTree = "<group>"; }; 7466 7467 41D51BB21E4E2E8100131A5B /* LibWebRTCAudioFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LibWebRTCAudioFormat.h; path = libwebrtc/LibWebRTCAudioFormat.h; sourceTree = "<group>"; }; 7468 41DE7C78222DA13C00532B65 /* StorageQuotaUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageQuotaUser.h; sourceTree = "<group>"; }; 7467 7469 41DE7C7A222DA13D00532B65 /* StorageQuotaManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageQuotaManager.cpp; sourceTree = "<group>"; }; 7468 7470 41DE7C7B222DA13E00532B65 /* StorageQuotaManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StorageQuotaManager.h; sourceTree = "<group>"; }; … … 17100 17102 41DE7C7A222DA13D00532B65 /* StorageQuotaManager.cpp */, 17101 17103 41DE7C7B222DA13E00532B65 /* StorageQuotaManager.h */, 17104 41DE7C78222DA13C00532B65 /* StorageQuotaUser.h */, 17102 17105 5166D3CC1E8ED41100AD62E3 /* StorageType.h */, 17103 17106 ); … … 32217 32220 1A37636C1A2E68BB009A7EE2 /* StorageNamespaceProvider.h in Headers */, 32218 32221 41DE7C7C222DA14300532B65 /* StorageQuotaManager.h in Headers */, 32222 41DE7C7D222DA14800532B65 /* StorageQuotaUser.h in Headers */, 32219 32223 5C9EF2F321F06190003BDC56 /* StorageSessionProvider.h in Headers */, 32220 32224 5166D3CD1E8ED48F00AD62E3 /* StorageType.h in Headers */, -
trunk/Source/WebCore/storage/StorageQuotaManager.cpp
r252805 r252839 28 28 29 29 #include "Logging.h" 30 #include <wtf/Ref.h> 31 #include <wtf/RefCounted.h> 32 #include <wtf/threads/BinarySemaphore.h> 30 #include "StorageQuotaUser.h" 33 31 34 32 namespace WebCore { 35 33 36 Ref<StorageQuotaManager> StorageQuotaManager::create(uint64_t quota, UsageGetter&& usageGetter, QuotaIncreaseRequester&& quotaIncreaseRequester) 37 { 38 return adoptRef(*new StorageQuotaManager(quota, WTFMove(usageGetter), WTFMove(quotaIncreaseRequester))); 39 } 40 41 StorageQuotaManager::StorageQuotaManager(uint64_t quota, UsageGetter&& usageGetter, QuotaIncreaseRequester&& quotaIncreaseRequester) 42 : m_quota(quota) 43 , m_usageGetter(WTFMove(usageGetter)) 44 , m_quotaIncreaseRequester(WTFMove(quotaIncreaseRequester)) 45 , m_workQueue(WorkQueue::create("StorageQuotaManager Background Queue", WorkQueue::Type::Serial)) 46 , m_initialQuota(quota) 47 { 48 } 49 50 void StorageQuotaManager::requestSpaceOnMainThread(uint64_t spaceRequested, RequestCallback&& callback) 51 { 52 ASSERT(isMainThread()); 53 54 // Fast path. 55 if (m_quotaCountDownLock.tryLock()) { 56 if (tryGrantRequest(spaceRequested)) { 57 m_quotaCountDownLock.unlock(); 58 callback(Decision::Grant); 59 return; 34 StorageQuotaManager::~StorageQuotaManager() 35 { 36 while (!m_pendingRequests.isEmpty()) 37 m_pendingRequests.takeFirst().callback(Decision::Deny); 38 } 39 40 uint64_t StorageQuotaManager::spaceUsage() const 41 { 42 uint64_t usage = 0; 43 for (auto& user : m_users) 44 usage += user->spaceUsed(); 45 return usage; 46 } 47 48 void StorageQuotaManager::updateQuotaBasedOnSpaceUsage() 49 { 50 if (!m_quota) 51 return; 52 53 auto defaultQuotaStep = m_quota / 10; 54 m_quota = std::max(m_quota, defaultQuotaStep * ((spaceUsage() / defaultQuotaStep) + 1)); 55 } 56 57 void StorageQuotaManager::initializeUsersIfNeeded() 58 { 59 if (m_pendingInitializationUsers.isEmpty()) 60 return; 61 62 Vector<StorageQuotaUser*> usersToInitialize; 63 for (auto& keyValue : m_pendingInitializationUsers) { 64 if (keyValue.value == WhenInitializedCalled::No) { 65 keyValue.value = WhenInitializedCalled::Yes; 66 usersToInitialize.append(keyValue.key); 60 67 } 61 m_quotaCountDownLock.unlock(); 62 } 63 64 m_workQueue->dispatch([this, protectedThis = makeRef(*this), spaceRequested, callback = WTFMove(callback)]() mutable { 65 auto decision = requestSpaceOnBackgroundThread(spaceRequested); 66 callOnMainThread([callback = WTFMove(callback), decision]() mutable { 67 callback(decision); 68 } 69 for (auto* user : usersToInitialize) { 70 if (m_pendingInitializationUsers.contains(user)) 71 askUserToInitialize(*user); 72 } 73 } 74 75 void StorageQuotaManager::askUserToInitialize(StorageQuotaUser& user) 76 { 77 user.whenInitialized([this, &user, weakThis = makeWeakPtr(this)]() { 78 if (!weakThis) 79 return; 80 81 if (m_pendingInitializationUsers.remove(&user)) 82 m_users.add(&user); 83 84 if (!m_pendingInitializationUsers.isEmpty()) 85 return; 86 87 // Make sure quota is set before handling first request. 88 if (m_state == State::Uninitialized) { 89 updateQuotaBasedOnSpaceUsage(); 90 m_state = State::MakingDecisionForRequest; 91 } 92 93 processPendingRequests({ }); 94 }); 95 } 96 97 void StorageQuotaManager::addUser(StorageQuotaUser& user) 98 { 99 ASSERT(!m_pendingInitializationUsers.contains(&user)); 100 ASSERT(!m_users.contains(&user)); 101 m_pendingInitializationUsers.add(&user, WhenInitializedCalled::No); 102 103 if (!m_pendingRequests.isEmpty()) 104 askUserToInitialize(user); 105 } 106 107 bool StorageQuotaManager::shouldAskForMoreSpace(uint64_t spaceIncrease) const 108 { 109 if (!spaceIncrease) 110 return false; 111 112 return spaceUsage() + spaceIncrease > m_quota; 113 } 114 115 void StorageQuotaManager::removeUser(StorageQuotaUser& user) 116 { 117 ASSERT(m_users.contains(&user) || m_pendingInitializationUsers.contains(&user)); 118 m_users.remove(&user); 119 if (m_pendingInitializationUsers.remove(&user) && m_pendingInitializationUsers.isEmpty()) { 120 // When being cleared, quota users may remove themselves and add themselves to trigger reinitialization. 121 // Let's wait for addUser to be called before processing pending requests. 122 callOnMainThread([this, weakThis = makeWeakPtr(this)] { 123 if (!weakThis) 124 return; 125 126 if (m_pendingInitializationUsers.isEmpty()) 127 this->processPendingRequests({ }); 68 128 }); 129 } 130 } 131 132 void StorageQuotaManager::requestSpace(uint64_t spaceIncrease, RequestCallback&& callback) 133 { 134 if (!m_pendingRequests.isEmpty()) { 135 m_pendingRequests.append({ spaceIncrease, WTFMove(callback) }); 136 return; 137 } 138 139 if (!spaceIncrease) { 140 callback(Decision::Grant); 141 return; 142 } 143 144 initializeUsersIfNeeded(); 145 146 if (!m_pendingInitializationUsers.isEmpty()) { 147 m_pendingRequests.append({ spaceIncrease, WTFMove(callback) }); 148 return; 149 } 150 151 if (shouldAskForMoreSpace(spaceIncrease)) { 152 m_pendingRequests.append({ spaceIncrease, WTFMove(callback) }); 153 154 // Try processing request again after making sure usage is accurate. 155 m_state = State::ComputingSpaceUsed; 156 for (auto& user : copyToVector(m_users)) 157 user->computeSpaceUsed(); 158 159 if (!m_pendingInitializationUsers.isEmpty()) 160 return; 161 162 m_state = State::AskingForMoreSpace; 163 askForMoreSpace(spaceIncrease); 164 return; 165 } 166 167 m_state = State::MakingDecisionForRequest; 168 callback(Decision::Grant); 169 } 170 171 void StorageQuotaManager::askForMoreSpace(uint64_t spaceIncrease) 172 { 173 ASSERT(shouldAskForMoreSpace(spaceIncrease)); 174 ASSERT(m_state == State::AskingForMoreSpace); 175 176 RELEASE_LOG(Storage, "%p - StorageQuotaManager::askForMoreSpace %" PRIu64, this, spaceIncrease); 177 m_state = State::WaitingForSpaceIncreaseResponse; 178 m_spaceIncreaseRequester(m_quota, spaceUsage(), spaceIncrease, [this, weakThis = makeWeakPtr(*this)](Optional<uint64_t> newQuota) { 179 if (!weakThis) 180 return; 181 182 RELEASE_LOG(Storage, "%p - StorageQuotaManager::askForMoreSpace received response %" PRIu64, this, newQuota ? *newQuota : 0); 183 184 m_state = State::AskingForMoreSpace; 185 processPendingRequests(newQuota); 69 186 }); 70 187 } 71 188 72 StorageQuotaManager::Decision StorageQuotaManager::requestSpaceOnBackgroundThread(uint64_t spaceRequested) 73 { 74 ASSERT(!isMainThread()); 75 76 LockHolder locker(m_quotaCountDownLock); 77 78 if (tryGrantRequest(spaceRequested)) 79 return Decision::Grant; 80 81 m_usage = m_usageGetter(); 82 updateQuotaBasedOnUsage(); 83 m_quotaCountDown = m_usage < m_quota ? m_quota - m_usage : 0; 84 if (tryGrantRequest(spaceRequested)) 85 return Decision::Grant; 86 87 // Block this thread until getting decsion for quota increase. 88 BinarySemaphore semaphore; 89 callOnMainThread([this, protectedThis = makeRef(*this), spaceRequested, &semaphore]() mutable { 90 RELEASE_LOG(Storage, "%p - StorageQuotaManager asks for quota increase %" PRIu64, this, spaceRequested); 91 m_quotaIncreaseRequester(m_quota, m_usage, spaceRequested, [this, protectedThis = WTFMove(protectedThis), &semaphore](Optional<uint64_t> newQuota) mutable { 92 RELEASE_LOG(Storage, "%p - StorageQuotaManager receives quota increase response %" PRIu64, this, newQuota ? *newQuota : 0); 93 ASSERT(isMainThread()); 94 95 if (newQuota) 96 m_quota = *newQuota; 97 98 semaphore.signal(); 99 }); 100 }); 101 102 semaphore.wait(); 103 104 m_usage = m_usageGetter(); 105 m_quotaCountDown = m_usage < m_quota ? m_quota - m_usage : 0; 106 return tryGrantRequest(spaceRequested) ? Decision::Grant : Decision::Deny; 107 } 108 109 bool StorageQuotaManager::tryGrantRequest(uint64_t spaceRequested) 110 { 111 ASSERT(m_quotaCountDownLock.isLocked()); 112 if (spaceRequested <= m_quotaCountDown) { 113 m_quotaCountDown -= spaceRequested; 114 return true; 115 } 116 return false; 117 } 118 119 void StorageQuotaManager::updateQuotaBasedOnUsage() 120 { 121 // When StorageQuotaManager is used for the first time, we want to make sure its initial quota is bigger than current disk usage, 122 // based on the assumption that the quota was increased to at least the disk usage under user's permission before. 123 ASSERT(m_quotaCountDownLock.isLocked()); 124 if (!m_quotaUpdatedBasedOnUsage) { 125 m_quotaUpdatedBasedOnUsage = true; 126 auto defaultQuotaStep = m_quota / 10; 127 m_quota = std::max(m_quota, defaultQuotaStep * ((m_usage / defaultQuotaStep) + 1)); 128 } 129 } 130 131 void StorageQuotaManager::resetQuotaUpdatedBasedOnUsageForTesting() 132 { 133 LockHolder locker(m_quotaCountDownLock); 134 m_quota = m_initialQuota; 135 m_quotaCountDown = 0; 136 m_quotaUpdatedBasedOnUsage = false; 137 } 138 139 void StorageQuotaManager::resetQuotaForTesting() 140 { 141 LockHolder locker(m_quotaCountDownLock); 142 m_quota = m_initialQuota; 143 m_quotaCountDown = 0; 189 void StorageQuotaManager::processPendingRequests(Optional<uint64_t> newQuota) 190 { 191 if (m_pendingRequests.isEmpty()) 192 return; 193 194 if (newQuota) 195 m_quota = *newQuota; 196 197 if (m_state == State::WaitingForSpaceIncreaseResponse) 198 return; 199 200 if (!m_pendingInitializationUsers.isEmpty()) 201 return; 202 203 if (m_state == State::AskingForMoreSpace) { 204 auto request = m_pendingRequests.takeFirst(); 205 bool shouldAllowRequest = !shouldAskForMoreSpace(request.spaceIncrease); 206 207 RELEASE_LOG(Storage, "%p - StorageQuotaManager::processPendingRequests first request decision is %d", this, shouldAllowRequest); 208 209 m_state = State::MakingDecisionForRequest; 210 request.callback(shouldAllowRequest ? Decision::Grant : Decision::Deny); 211 } 212 213 while (!m_pendingRequests.isEmpty()) { 214 auto& request = m_pendingRequests.first(); 215 216 if (shouldAskForMoreSpace(request.spaceIncrease)) { 217 if (m_state == State::MakingDecisionForRequest) { 218 m_state = State::ComputingSpaceUsed; 219 for (auto& user : copyToVector(m_users)) 220 user->computeSpaceUsed(); 221 222 if (!m_pendingInitializationUsers.isEmpty()) 223 return; 224 } 225 226 m_state = State::AskingForMoreSpace; 227 uint64_t spaceIncrease = 0; 228 for (auto& pendingRequest : m_pendingRequests) 229 spaceIncrease += pendingRequest.spaceIncrease; 230 askForMoreSpace(spaceIncrease); 231 return; 232 } 233 234 m_state = State::MakingDecisionForRequest; 235 m_pendingRequests.takeFirst().callback(Decision::Grant); 236 } 144 237 } 145 238 -
trunk/Source/WebCore/storage/StorageQuotaManager.h
r252805 r252839 26 26 #pragma once 27 27 28 #include "ClientOrigin.h" 28 29 #include <wtf/CompletionHandler.h> 29 30 #include <wtf/Deque.h> … … 31 32 #include <wtf/HashSet.h> 32 33 #include <wtf/WeakPtr.h> 33 #include <wtf/WorkQueue.h>34 34 35 35 namespace WebCore { 36 36 37 class StorageQuotaManager : public ThreadSafeRefCounted<StorageQuotaManager>, public CanMakeWeakPtr<StorageQuotaManager> { 37 class StorageQuotaUser; 38 39 class StorageQuotaManager : public CanMakeWeakPtr<StorageQuotaManager> { 38 40 WTF_MAKE_FAST_ALLOCATED; 39 41 public: 40 using UsageGetter = Function<uint64_t()>; 41 using QuotaIncreaseRequester = Function<void(uint64_t currentQuota, uint64_t currentUsage, uint64_t requestedIncrease, CompletionHandler<void(Optional<uint64_t>)>&&)>; 42 WEBCORE_EXPORT static Ref<StorageQuotaManager> create(uint64_t quota, UsageGetter&&, QuotaIncreaseRequester&&); 42 using SpaceIncreaseRequester = WTF::Function<void(uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, CompletionHandler<void(Optional<uint64_t>)>&&)>; 43 StorageQuotaManager(uint64_t quota, SpaceIncreaseRequester&& spaceIncreaseRequester) 44 : m_quota(quota) 45 , m_spaceIncreaseRequester(WTFMove(spaceIncreaseRequester)) 46 { 47 } 48 WEBCORE_EXPORT ~StorageQuotaManager(); 43 49 44 50 static constexpr uint64_t defaultThirdPartyQuotaFromPerOriginQuota(uint64_t quota) { return quota / 10; } 51 45 52 static constexpr uint64_t defaultQuota() { return 1000 * MB; } 46 53 static constexpr uint64_t defaultThirdPartyQuota() { return defaultThirdPartyQuotaFromPerOriginQuota(defaultQuota()); } 47 54 55 WEBCORE_EXPORT void addUser(StorageQuotaUser&); 56 WEBCORE_EXPORT void removeUser(StorageQuotaUser&); 57 48 58 enum class Decision { Deny, Grant }; 49 59 using RequestCallback = CompletionHandler<void(Decision)>; 50 WEBCORE_EXPORT void requestSpace OnMainThread(uint64_t, RequestCallback&&);51 WEBCORE_EXPORT Decision requestSpaceOnBackgroundThread(uint64_t);60 WEBCORE_EXPORT void requestSpace(uint64_t, RequestCallback&&); 61 void resetQuota(uint64_t newQuota) { m_quota = newQuota; } 52 62 53 WEBCORE_EXPORT void resetQuotaUpdatedBasedOnUsageForTesting(); 54 WEBCORE_EXPORT void resetQuotaForTesting(); 63 WEBCORE_EXPORT void updateQuotaBasedOnSpaceUsage(); 64 65 enum class State { 66 Uninitialized, 67 ComputingSpaceUsed, 68 WaitingForSpaceIncreaseResponse, 69 AskingForMoreSpace, 70 MakingDecisionForRequest, 71 }; 72 State state() const { return m_state; } 55 73 56 74 private: 57 StorageQuotaManager(uint64_t quota, UsageGetter&&, QuotaIncreaseRequester&&); 58 bool tryGrantRequest(uint64_t); 75 uint64_t spaceUsage() const; 76 bool shouldAskForMoreSpace(uint64_t spaceIncrease) const; 77 void askForMoreSpace(uint64_t spaceIncrease); 59 78 60 void updateQuotaBasedOnUsage(); 79 void initializeUsersIfNeeded(); 80 void askUserToInitialize(StorageQuotaUser&); 61 81 62 Lock m_quotaCountDownLock;63 uint64_t m_quotaCountDown { 0 }; 82 void processPendingRequests(Optional<uint64_t>); 83 64 84 uint64_t m_quota { 0 }; 65 uint64_t m_usage { 0 };66 85 67 UsageGetter m_usageGetter; 68 QuotaIncreaseRequester m_quotaIncreaseRequester; 86 SpaceIncreaseRequester m_spaceIncreaseRequester; 69 87 70 Ref<WorkQueue> m_workQueue; 88 enum class WhenInitializedCalled { No, Yes }; 89 HashMap<StorageQuotaUser*, WhenInitializedCalled> m_pendingInitializationUsers; 90 HashSet<StorageQuotaUser*> m_users; 71 91 72 bool m_quotaUpdatedBasedOnUsage { false }; 92 struct PendingRequest { 93 uint64_t spaceIncrease; 94 RequestCallback callback; 95 }; 96 Deque<PendingRequest> m_pendingRequests; 73 97 74 // Test only. 75 uint64_t m_initialQuota { 0 }; 98 State m_state { State::Uninitialized }; 76 99 }; 77 100 -
trunk/Source/WebKit/ChangeLog
r252819 r252839 1 2019-11-23 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r252805. 4 https://bugs.webkit.org/show_bug.cgi?id=204553 5 6 Caused test failures and ASan crashes (Requested by ap on 7 #webkit). 8 9 Reverted changeset: 10 11 "Cross-thread version StorageQuotaManager" 12 https://bugs.webkit.org/show_bug.cgi?id=203971 13 https://trac.webkit.org/changeset/252805 14 1 15 2019-11-22 Alex Christensen <achristensen@webkit.org> 2 16 -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.cpp
r252819 r252839 66 66 #include "WebsiteDataStoreParameters.h" 67 67 #include "WebsiteDataType.h" 68 #include <WebCore/ClientOrigin.h>69 68 #include <WebCore/CookieJar.h> 70 69 #include <WebCore/DNS.h> … … 318 317 setSession(sessionID, NetworkSession::create(*this, WTFMove(parameters.defaultDataStoreParameters.networkSessionParameters))); 319 318 320 SandboxExtension::consumePermanently(parameters.defaultDataStoreParameters.cacheStorageDirectoryExtensionHandle);321 addSessionStorageQuotaManager(sessionID, parameters.defaultDataStoreParameters.perOriginStorageQuota, parameters.defaultDataStoreParameters.perThirdPartyOriginStorageQuota, parameters.defaultDataStoreParameters.cacheStorageDirectory, parameters.defaultDataStoreParameters.cacheStorageDirectoryExtensionHandle);322 323 319 #if ENABLE(INDEXED_DATABASE) 324 320 addIndexedDatabaseSession(sessionID, parameters.defaultDataStoreParameters.indexedDatabaseDirectory, parameters.defaultDataStoreParameters.indexedDatabaseDirectoryExtensionHandle); … … 331 327 } 332 328 #endif 329 initializeStorageQuota(parameters.defaultDataStoreParameters); 333 330 334 331 m_storageManagerSet->add(sessionID, parameters.defaultDataStoreParameters.localStorageDirectory, parameters.defaultDataStoreParameters.localStorageDirectoryExtensionHandle); … … 438 435 void NetworkProcess::addWebsiteDataStore(WebsiteDataStoreParameters&& parameters) 439 436 { 440 auto sessionID = parameters.networkSessionParameters.sessionID;441 442 addSessionStorageQuotaManager(sessionID, parameters.perOriginStorageQuota, parameters.perThirdPartyOriginStorageQuota, parameters.cacheStorageDirectory, parameters.cacheStorageDirectoryExtensionHandle);443 444 437 #if ENABLE(INDEXED_DATABASE) 445 addIndexedDatabaseSession( sessionID, parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle);438 addIndexedDatabaseSession(parameters.networkSessionParameters.sessionID, parameters.indexedDatabaseDirectory, parameters.indexedDatabaseDirectoryExtensionHandle); 446 439 #endif 447 440 448 441 #if ENABLE(SERVICE_WORKER) 449 442 if (parentProcessHasServiceWorkerEntitlement()) 450 addServiceWorkerSession(sessionID, parameters.serviceWorkerProcessTerminationDelayEnabled, WTFMove(parameters.serviceWorkerRegistrationDirectory), parameters.serviceWorkerRegistrationDirectoryExtensionHandle); 451 #endif 452 453 m_storageManagerSet->add(sessionID, parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle); 443 addServiceWorkerSession(parameters.networkSessionParameters.sessionID, parameters.serviceWorkerProcessTerminationDelayEnabled, WTFMove(parameters.serviceWorkerRegistrationDirectory), parameters.serviceWorkerRegistrationDirectoryExtensionHandle); 444 #endif 445 446 m_storageManagerSet->add(parameters.networkSessionParameters.sessionID, parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle); 447 448 initializeStorageQuota(parameters); 454 449 455 450 RemoteNetworkingContext::ensureWebsiteDataStoreSession(*this, WTFMove(parameters)); 456 451 } 457 452 458 void NetworkProcess::addSessionStorageQuotaManager(PAL::SessionID sessionID, uint64_t defaultQuota, uint64_t defaultThirdPartyQuota, const String& cacheRootPath, SandboxExtension::Handle& cacheRootPathHandle) 459 { 460 LockHolder locker(m_sessionStorageQuotaManagersLock); 461 auto [iter, isNewEntry] = m_sessionStorageQuotaManagers.ensure(sessionID, [defaultQuota, defaultThirdPartyQuota, &cacheRootPath] { 462 return makeUnique<SessionStorageQuotaManager>(cacheRootPath, defaultQuota, defaultThirdPartyQuota); 463 }); 464 if (isNewEntry) 465 SandboxExtension::consumePermanently(cacheRootPathHandle); 466 } 467 468 void NetworkProcess::removeSessionStorageQuotaManager(PAL::SessionID sessionID) 469 { 470 LockHolder locker(m_sessionStorageQuotaManagersLock); 471 ASSERT(m_sessionStorageQuotaManagers.contains(sessionID)); 472 m_sessionStorageQuotaManagers.remove(sessionID); 453 void NetworkProcess::initializeStorageQuota(const WebsiteDataStoreParameters& parameters) 454 { 455 auto& managers = m_storageQuotaManagers.ensure(parameters.networkSessionParameters.sessionID, [] { 456 return StorageQuotaManagers { }; 457 }).iterator->value; 458 managers.setDefaultQuotas(parameters.perOriginStorageQuota, parameters.perThirdPartyOriginStorageQuota); 473 459 } 474 460 … … 591 577 592 578 m_storageManagerSet->remove(sessionID); 579 580 m_storageQuotaManagers.remove(sessionID); 593 581 } 594 582 … … 1481 1469 clearDiskCache(modifiedSince, [clearTasksHandler = WTFMove(clearTasksHandler)] { }); 1482 1470 1471 if (websiteDataTypes.contains(WebsiteDataType::IndexedDBDatabases) || websiteDataTypes.contains(WebsiteDataType::DOMCache)) 1472 clearStorageQuota(sessionID); 1473 1483 1474 if (websiteDataTypes.contains(WebsiteDataType::AdClickAttributions)) { 1484 1475 if (auto* networkSession = this->networkSession(sessionID)) … … 1573 1564 WebCore::CredentialStorage::removeSessionCredentialsWithOrigins(originDatas); 1574 1565 } 1566 1567 // FIXME: Implement storage quota clearing for these origins. 1568 } 1569 1570 void NetworkProcess::clearStorageQuota(PAL::SessionID sessionID) 1571 { 1572 auto iterator = m_storageQuotaManagers.find(sessionID); 1573 if (iterator == m_storageQuotaManagers.end()) 1574 return; 1575 1576 auto& managers = iterator->value; 1577 for (auto& manager : managers.managersPerOrigin()) 1578 manager.value->resetQuota(managers.defaultQuota(manager.key)); 1575 1579 } 1576 1580 … … 2214 2218 } 2215 2219 2216 return IDBServer::IDBServer::create(sessionID, path, [this, weakThis = makeWeakPtr(this), sessionID](const auto& origin, uint64_t spaceRequested) { 2217 RefPtr<StorageQuotaManager> storageQuotaManager = weakThis ? this->storageQuotaManager(sessionID, origin) : nullptr; 2218 return storageQuotaManager ? storageQuotaManager->requestSpaceOnBackgroundThread(spaceRequested) : StorageQuotaManager::Decision::Deny; 2220 return IDBServer::IDBServer::create(sessionID, path, [this, weakThis = makeWeakPtr(this)](PAL::SessionID sessionID, const auto& origin) -> StorageQuotaManager* { 2221 if (!weakThis) 2222 return nullptr; 2223 return &this->storageQuotaManager(sessionID, origin); 2219 2224 }); 2220 2225 } … … 2303 2308 if (!indexedDatabaseDirectory.isEmpty()) 2304 2309 postStorageTask(createCrossThreadTask(*this, &NetworkProcess::ensurePathExists, indexedDatabaseDirectory)); 2305 setSessionStorageQuotaManagerIDBRootPath(sessionID, indexedDatabaseDirectory); 2306 } 2307 } 2308 2309 void NetworkProcess::setSessionStorageQuotaManagerIDBRootPath(PAL::SessionID sessionID, const String& idbRootPath) 2310 { 2311 LockHolder locker(m_sessionStorageQuotaManagersLock); 2312 auto* sessionStorageQuotaManager = m_sessionStorageQuotaManagers.get(sessionID); 2313 ASSERT(sessionStorageQuotaManager); 2314 sessionStorageQuotaManager->setIDBRootPath(idbRootPath); 2315 } 2316 2310 } 2311 } 2317 2312 #endif // ENABLE(INDEXED_DATABASE) 2318 2313 … … 2331 2326 void NetworkProcess::updateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID sessionID, const ClientOrigin& origin) 2332 2327 { 2333 auto storageQuotaManager = this->storageQuotaManager(sessionID, origin); 2334 storageQuotaManager->resetQuotaUpdatedBasedOnUsageForTesting(); 2335 } 2336 2337 void NetworkProcess::resetQuota(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler) 2338 { 2339 LockHolder locker(m_sessionStorageQuotaManagersLock); 2340 if (auto* sessionStorageQuotaManager = m_sessionStorageQuotaManagers.get(sessionID)) { 2341 for (auto storageQuotaManager : sessionStorageQuotaManager->existingStorageQuotaManagers()) 2342 storageQuotaManager->resetQuotaForTesting(); 2343 } 2344 completionHandler(); 2328 auto& manager = storageQuotaManager(sessionID, origin); 2329 manager.resetQuota(m_storageQuotaManagers.find(sessionID)->value.defaultQuota(origin)); 2330 manager.updateQuotaBasedOnSpaceUsage(); 2345 2331 } 2346 2332 … … 2419 2405 } 2420 2406 2421 RefPtr<StorageQuotaManager> NetworkProcess::storageQuotaManager(PAL::SessionID sessionID, const ClientOrigin& origin) 2422 { 2423 LockHolder locker(m_sessionStorageQuotaManagersLock); 2424 auto* sessionStorageQuotaManager = m_sessionStorageQuotaManagers.get(sessionID); 2425 if (!sessionStorageQuotaManager) 2426 return nullptr; 2427 2428 String idbRootPath; 2429 #if ENABLE(INDEXED_DATABASE) 2430 idbRootPath = sessionStorageQuotaManager->idbRootPath(); 2431 #endif 2432 StorageQuotaManager::UsageGetter usageGetter = [cacheRootPath = sessionStorageQuotaManager->cacheRootPath().isolatedCopy(), idbRootPath = idbRootPath.isolatedCopy(), origin = origin.isolatedCopy()]() { 2433 ASSERT(!isMainThread()); 2434 2435 uint64_t usage = CacheStorage::Engine::diskUsage(cacheRootPath, origin); 2436 #if ENABLE(INDEXED_DATABASE) 2437 usage += IDBServer::IDBServer::diskUsage(idbRootPath, origin); 2438 #endif 2439 2440 return usage; 2441 }; 2442 StorageQuotaManager::QuotaIncreaseRequester quotaIncreaseRequester = [this, weakThis = makeWeakPtr(*this), sessionID, origin] (uint64_t currentQuota, uint64_t currentSpace, uint64_t requestedIncrease, auto&& callback) { 2443 ASSERT(isMainThread()); 2407 class QuotaUserInitializer final : public WebCore::StorageQuotaUser { 2408 WTF_MAKE_FAST_ALLOCATED; 2409 public: 2410 explicit QuotaUserInitializer(StorageQuotaManager& manager) 2411 : m_manager(makeWeakPtr(manager)) 2412 { 2413 manager.addUser(*this); 2414 } 2415 2416 ~QuotaUserInitializer() 2417 { 2418 if (m_manager) 2419 m_manager->removeUser(*this); 2420 if (m_callback) 2421 m_callback(); 2422 } 2423 2424 private: 2425 // StorageQuotaUser API. 2426 uint64_t spaceUsed() const final 2427 { 2428 ASSERT_NOT_REACHED(); 2429 return 0; 2430 } 2431 2432 void whenInitialized(CompletionHandler<void()>&& callback) final 2433 { 2434 m_callback = WTFMove(callback); 2435 } 2436 2437 WeakPtr<StorageQuotaManager> m_manager; 2438 CompletionHandler<void()> m_callback; 2439 }; 2440 2441 void NetworkProcess::initializeQuotaUsers(StorageQuotaManager& manager, PAL::SessionID sessionID, const ClientOrigin& origin) 2442 { 2443 RunLoop::main().dispatch([this, weakThis = makeWeakPtr(this), sessionID, origin, user = makeUnique<QuotaUserInitializer>(manager)]() mutable { 2444 2444 if (!weakThis) 2445 callback({ }); 2446 requestStorageSpace(sessionID, origin, currentQuota, currentSpace, requestedIncrease, WTFMove(callback)); 2447 }; 2448 2449 return sessionStorageQuotaManager->ensureOriginStorageQuotaManager(origin, sessionStorageQuotaManager->defaultQuota(origin), WTFMove(usageGetter), WTFMove(quotaIncreaseRequester)).ptr(); 2445 return; 2446 this->idbServer(sessionID).initializeQuotaUser(origin); 2447 CacheStorage::Engine::initializeQuotaUser(*this, sessionID, origin, [user = WTFMove(user)] { }); 2448 }); 2449 } 2450 2451 StorageQuotaManager& NetworkProcess::storageQuotaManager(PAL::SessionID sessionID, const ClientOrigin& origin) 2452 { 2453 auto& storageQuotaManagers = m_storageQuotaManagers.ensure(sessionID, [] { 2454 return StorageQuotaManagers { }; 2455 }).iterator->value; 2456 return *storageQuotaManagers.managersPerOrigin().ensure(origin, [this, &storageQuotaManagers, sessionID, &origin] { 2457 auto manager = makeUnique<StorageQuotaManager>(storageQuotaManagers.defaultQuota(origin), [this, sessionID, origin](uint64_t quota, uint64_t currentSpace, uint64_t spaceIncrease, auto callback) { 2458 this->requestStorageSpace(sessionID, origin, quota, currentSpace, spaceIncrease, WTFMove(callback)); 2459 }); 2460 initializeQuotaUsers(*manager, sessionID, origin); 2461 return manager; 2462 }).iterator->value; 2450 2463 } 2451 2464 -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.h
r252819 r252839 285 285 286 286 void updateQuotaBasedOnSpaceUsageForTesting(PAL::SessionID, const WebCore::ClientOrigin&); 287 void resetQuota(PAL::SessionID, CompletionHandler<void()>&&);288 287 289 288 #if ENABLE(SANDBOX_EXTENSIONS) … … 329 328 void markAdClickAttributionsAsExpiredForTesting(PAL::SessionID, CompletionHandler<void()>&&); 330 329 331 RefPtr<WebCore::StorageQuotaManager>storageQuotaManager(PAL::SessionID, const WebCore::ClientOrigin&);330 WebCore::StorageQuotaManager& storageQuotaManager(PAL::SessionID, const WebCore::ClientOrigin&); 332 331 333 332 void addKeptAliveLoad(Ref<NetworkResourceLoader>&&); … … 444 443 HashSet<WebCore::SecurityOriginData> indexedDatabaseOrigins(const String& path); 445 444 Ref<WebCore::IDBServer::IDBServer> createIDBServer(PAL::SessionID); 446 void setSessionStorageQuotaManagerIDBRootPath(PAL::SessionID, const String& idbRootPath);447 445 #endif 448 446 … … 464 462 void ensurePathExists(const String& path); 465 463 466 class SessionStorageQuotaManager { 467 WTF_MAKE_FAST_ALLOCATED; 468 public: 469 SessionStorageQuotaManager(const String& cacheRootPath, uint64_t defaultQuota, uint64_t defaultThirdPartyQuota) 470 : m_cacheRootPath(cacheRootPath) 471 , m_defaultQuota(defaultQuota) 472 , m_defaultThirdPartyQuota(defaultThirdPartyQuota) 473 { 474 } 475 uint64_t defaultQuota(const WebCore::ClientOrigin& origin) const { return origin.topOrigin == origin.clientOrigin ? m_defaultQuota : m_defaultThirdPartyQuota; } 476 477 Ref<WebCore::StorageQuotaManager> ensureOriginStorageQuotaManager(WebCore::ClientOrigin origin, uint64_t quota, WebCore::StorageQuotaManager::UsageGetter&& usageGetter, WebCore::StorageQuotaManager::QuotaIncreaseRequester&& quotaIncreaseRequester) 478 { 479 auto [iter, isNewEntry] = m_storageQuotaManagers.ensure(origin, [quota, usageGetter = WTFMove(usageGetter), quotaIncreaseRequester = WTFMove(quotaIncreaseRequester)]() mutable { 480 return WebCore::StorageQuotaManager::create(quota, WTFMove(usageGetter), WTFMove(quotaIncreaseRequester)); 481 }); 482 return makeRef(*iter->value); 483 } 484 485 auto existingStorageQuotaManagers() { return m_storageQuotaManagers.values(); } 486 487 const String& cacheRootPath() const { return m_cacheRootPath; } 488 #if ENABLE(INDEXED_DATABASE) 489 void setIDBRootPath(const String& idbRootPath) { m_idbRootPath = idbRootPath; } 490 const String& idbRootPath() const { return m_idbRootPath; } 491 #endif 492 493 private: 494 String m_cacheRootPath; 495 #if ENABLE(INDEXED_DATABASE) 496 String m_idbRootPath; 497 #endif 498 uint64_t m_defaultQuota { WebCore::StorageQuotaManager::defaultQuota() }; 499 uint64_t m_defaultThirdPartyQuota { WebCore::StorageQuotaManager::defaultThirdPartyQuota() }; 500 HashMap<WebCore::ClientOrigin, RefPtr<WebCore::StorageQuotaManager>> m_storageQuotaManagers; 501 }; 502 void addSessionStorageQuotaManager(PAL::SessionID, uint64_t defaultQuota, uint64_t defaultThirdPartyQuota, const String& cacheRootPath, SandboxExtension::Handle&); 503 void removeSessionStorageQuotaManager(PAL::SessionID); 464 void clearStorageQuota(PAL::SessionID); 465 void initializeStorageQuota(const WebsiteDataStoreParameters&); 504 466 505 467 // Connections to WebProcesses. … … 572 534 #endif 573 535 574 Lock m_sessionStorageQuotaManagersLock; 575 HashMap<PAL::SessionID, std::unique_ptr<SessionStorageQuotaManager>> m_sessionStorageQuotaManagers; 536 class StorageQuotaManagers { 537 public: 538 uint64_t defaultQuota(const WebCore::ClientOrigin& origin) const { return origin.topOrigin == origin.clientOrigin ? m_defaultQuota : m_defaultThirdPartyQuota; } 539 void setDefaultQuotas(uint64_t defaultQuota, uint64_t defaultThirdPartyQuota) 540 { 541 m_defaultQuota = defaultQuota; 542 m_defaultThirdPartyQuota = defaultThirdPartyQuota; 543 } 544 545 HashMap<WebCore::ClientOrigin, std::unique_ptr<WebCore::StorageQuotaManager>>& managersPerOrigin() { return m_managersPerOrigin; } 546 547 private: 548 uint64_t m_defaultQuota { WebCore::StorageQuotaManager::defaultQuota() }; 549 uint64_t m_defaultThirdPartyQuota { WebCore::StorageQuotaManager::defaultThirdPartyQuota() }; 550 HashMap<WebCore::ClientOrigin, std::unique_ptr<WebCore::StorageQuotaManager>> m_managersPerOrigin; 551 }; 552 HashMap<PAL::SessionID, StorageQuotaManagers> m_storageQuotaManagers; 576 553 577 554 OptionSet<NetworkCache::CacheOption> m_cacheOptions; -
trunk/Source/WebKit/NetworkProcess/NetworkProcess.messages.in
r252819 r252839 164 164 SetServiceWorkerFetchTimeoutForTesting(Seconds seconds) -> () Synchronous 165 165 ResetServiceWorkerFetchTimeoutForTesting() -> () Synchronous 166 167 ResetQuota(PAL::SessionID sessionID) -> () Async168 166 } -
trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.cpp
r252805 r252839 197 197 } 198 198 199 static uint64_t getDirectorySize(const String& directoryPath) 200 { 201 ASSERT(!isMainThread()); 202 203 uint64_t directorySize = 0; 204 Deque<String> paths; 205 paths.append(directoryPath); 206 while (!paths.isEmpty()) { 207 auto path = paths.takeFirst(); 208 if (FileSystem::fileIsDirectory(path, FileSystem::ShouldFollowSymbolicLinks::No)) { 209 auto newPaths = FileSystem::listDirectory(path, "*"_s); 210 for (auto& newPath : newPaths) { 211 // Files in /Blobs directory are hard link. 212 auto fileName = FileSystem::lastComponentOfPathIgnoringTrailingSlash(newPath); 213 if (fileName == "Blobs") 214 continue; 215 paths.append(newPath); 216 } 217 continue; 218 } 219 220 long long fileSize = 0; 221 FileSystem::getFileSize(path, fileSize); 222 directorySize += fileSize; 223 } 224 return directorySize; 225 } 226 227 uint64_t Engine::diskUsage(const String& rootPath, const WebCore::ClientOrigin& origin) 228 { 229 ASSERT(!isMainThread()); 230 231 if (rootPath.isEmpty()) 232 return 0; 233 234 String saltPath = FileSystem::pathByAppendingComponent(rootPath, "salt"_s); 235 auto salt = readOrMakeSalt(saltPath); 236 if (!salt) 237 return 0; 238 239 Key key(origin.topOrigin.toString(), origin.clientOrigin.toString(), { }, { }, *salt); 240 String directoryPath = FileSystem::pathByAppendingComponent(rootPath, key.hashAsString()); 241 242 String sizeFilePath = Caches::cachesSizeFilename(directoryPath); 243 if (auto recordedSize = readSizeFile(sizeFilePath)) 244 return *recordedSize; 245 246 return getDirectorySize(directoryPath); 247 } 248 249 void Engine::requestSpace(const ClientOrigin& origin, uint64_t spaceRequested, CompletionHandler<void(WebCore::StorageQuotaManager::Decision)>&& callback) 250 { 251 ASSERT(isMainThread()); 252 253 if (!m_networkProcess) 254 callback(WebCore::StorageQuotaManager::Decision::Deny); 255 256 RefPtr<WebCore::StorageQuotaManager> storageQuotaManager = m_networkProcess->storageQuotaManager(m_sessionID, origin); 257 if (!storageQuotaManager) 258 callback(WebCore::StorageQuotaManager::Decision::Deny); 259 260 storageQuotaManager->requestSpaceOnMainThread(spaceRequested, WTFMove(callback)); 199 void Engine::initializeQuotaUser(NetworkProcess& networkProcess, PAL::SessionID sessionID, const WebCore::ClientOrigin& clientOrigin, CompletionHandler<void()>&& completionHandler) 200 { 201 from(networkProcess, sessionID, [clientOrigin, completionHandler = WTFMove(completionHandler)](auto& engine) mutable { 202 engine.readCachesFromDisk(clientOrigin, [completionHandler = WTFMove(completionHandler)](auto&& cachesOrError) mutable { 203 completionHandler(); 204 }); 205 }); 261 206 } 262 207 … … 397 342 auto& caches = m_caches.ensure(origin, [&origin, this] { 398 343 auto path = cachesRootPath(origin); 399 return Caches::create(*this, WebCore::ClientOrigin { origin }, WTFMove(path) );344 return Caches::create(*this, WebCore::ClientOrigin { origin }, WTFMove(path), m_networkProcess->storageQuotaManager(m_sessionID, origin)); 400 345 }).iterator->value; 401 346 … … 529 474 } 530 475 531 void Engine::writeSizeFile(const String& path, uint64_t size, CompletionHandler<void()>&& completionHandler) 532 { 533 CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler)); 476 void Engine::writeSizeFile(const String& path, uint64_t size) 477 { 534 478 if (!shouldPersist()) 535 479 return; 536 480 537 m_ioQueue->dispatch([path = path.isolatedCopy(), size , completionHandlerCaller = WTFMove(completionHandlerCaller)]() mutable{481 m_ioQueue->dispatch([path = path.isolatedCopy(), size]() { 538 482 LockHolder locker(globalSizeFileLock); 539 483 auto fileHandle = FileSystem::openFile(path, FileSystem::FileOpenMode::Write); … … 546 490 FileSystem::truncateFile(fileHandle, 0); 547 491 FileSystem::writeToFile(fileHandle, String::number(size).utf8().data(), String::number(size).utf8().length()); 548 549 RunLoop::main().dispatch([completionHandlerCaller = WTFMove(completionHandlerCaller)]() mutable { });550 492 }); 551 493 } … … 572 514 return WTF::nullopt; 573 515 574 Vector< unsignedchar> buffer(bytesToRead);575 size_t totalBytesRead = FileSystem::readFromFile(fileHandle, reinterpret_cast<char*>(buffer.data()), buffer.size());516 Vector<char> buffer(bytesToRead); 517 size_t totalBytesRead = FileSystem::readFromFile(fileHandle, buffer.data(), buffer.size()); 576 518 if (totalBytesRead != bytesToRead) 577 519 return WTF::nullopt; -
trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngine.h
r252805 r252839 30 30 #include "WebsiteData.h" 31 31 #include <WebCore/ClientOrigin.h> 32 #include <WebCore/StorageQuotaManager.h>33 32 #include <pal/SessionID.h> 34 33 #include <wtf/HashMap.h> … … 81 80 static void initializeQuotaUser(NetworkProcess&, PAL::SessionID, const WebCore::ClientOrigin&, CompletionHandler<void()>&&); 82 81 83 static uint64_t diskUsage(const String& rootPath, const WebCore::ClientOrigin&);84 void requestSpace(const WebCore::ClientOrigin&, uint64_t spaceRequested, CompletionHandler<void(WebCore::StorageQuotaManager::Decision)>&&);85 86 82 bool shouldPersist() const { return !!m_ioQueue;} 87 83 … … 89 85 void readFile(const String& filename, CompletionHandler<void(const NetworkCache::Data&, int error)>&&); 90 86 void removeFile(const String& filename); 91 void writeSizeFile(const String&, uint64_t size , CompletionHandler<void()>&&);87 void writeSizeFile(const String&, uint64_t size); 92 88 static Optional<uint64_t> readSizeFile(const String&); 93 89 -
trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCache.cpp
r252805 r252839 415 415 416 416 spaceRequired += record.responseBodySize; 417 if (position != notFound) { 418 uint64_t spaceDecreased = sameURLRecords->at(position).size; 419 if (spaceRequired >= spaceDecreased) 420 spaceRequired -= spaceDecreased; 421 } 417 if (position != notFound) 418 spaceRequired -= sameURLRecords->at(position).size; 422 419 } 423 420 … … 454 451 }); 455 452 456 // This operation would change caches size, so make sure callback finishes after size file is updated. 457 m_caches.updateSizeFile([callback = WTFMove(callback), recordIdentifiers = WTFMove(recordIdentifiers)]() mutable { 458 callback(WTFMove(recordIdentifiers)); 459 }); 453 callback(WTFMove(recordIdentifiers)); 460 454 } 461 455 -
trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.cpp
r252805 r252839 57 57 } 58 58 59 Ref<Caches> Caches::create(Engine& engine, WebCore::ClientOrigin&& origin, String&& rootPath) 60 { 61 return adoptRef(*new Caches { engine, WTFMove(origin), WTFMove(rootPath) }); 62 } 63 64 Caches::Caches(Engine& engine, WebCore::ClientOrigin&& origin, String&& rootPath) 59 Ref<Caches> Caches::create(Engine& engine, WebCore::ClientOrigin&& origin, String&& rootPath, WebCore::StorageQuotaManager& quotaManager) 60 { 61 auto caches = adoptRef(*new Caches { engine, WTFMove(origin), WTFMove(rootPath), quotaManager }); 62 quotaManager.addUser(caches.get()); 63 return caches; 64 } 65 66 Caches::Caches(Engine& engine, WebCore::ClientOrigin&& origin, String&& rootPath, WebCore::StorageQuotaManager& quotaManager) 65 67 : m_engine(&engine) 66 68 , m_origin(WTFMove(origin)) 67 69 , m_rootPath(WTFMove(rootPath)) 70 , m_quotaManager(makeWeakPtr(quotaManager)) 68 71 { 69 72 } … … 72 75 { 73 76 ASSERT(m_pendingWritingCachesToDiskCallbacks.isEmpty()); 77 78 if (m_quotaManager) 79 m_quotaManager->removeUser(*this); 80 } 81 82 void Caches::whenInitialized(CompletionHandler<void()>&& callback) 83 { 84 initialize([callback = WTFMove(callback)](auto&& error) mutable { 85 if (error) 86 RELEASE_LOG_ERROR(CacheStorage, "Caches::initialize failed, reported space used will be zero"); 87 callback(); 88 }); 74 89 } 75 90 … … 194 209 } 195 210 196 void Caches::updateSizeFile(CompletionHandler<void()>&& completionHandler) 197 { 198 if (!m_engine) { 199 completionHandler(); 200 return; 201 } 202 203 m_engine->writeSizeFile(cachesSizeFilename(m_rootPath), m_size, WTFMove(completionHandler)); 211 void Caches::updateSizeFile() 212 { 213 if (m_engine) 214 m_engine->writeSizeFile(cachesSizeFilename(m_rootPath), m_size); 204 215 } 205 216 … … 222 233 } 223 234 m_size = size; 224 updateSizeFile([this, protectedThis = WTFMove(protectedThis)]() mutable { 225 m_isInitialized = true; 226 auto pendingCallbacks = WTFMove(m_pendingInitializationCallbacks); 227 for (auto& callback : pendingCallbacks) 228 callback(WTF::nullopt); 229 }); 235 updateSizeFile(); 236 237 m_isInitialized = true; 238 auto pendingCallbacks = WTFMove(m_pendingInitializationCallbacks); 239 for (auto& callback : pendingCallbacks) 240 callback(WTF::nullopt); 241 230 242 return; 231 243 } … … 262 274 ASSERT(RunLoop::isMain()); 263 275 protectedThis->clearMemoryRepresentation(); 276 protectedThis->resetSpaceUsed(); 264 277 completionHandler(); 265 278 }); … … 267 280 } 268 281 clearMemoryRepresentation(); 282 resetSpaceUsed(); 269 283 clearPendingWritingCachesToDiskCallbacks(); 270 284 completionHandler(); … … 512 526 void Caches::requestSpace(uint64_t spaceRequired, WebCore::DOMCacheEngine::CompletionCallback&& callback) 513 527 { 514 if (!m_ engine) {528 if (!m_quotaManager) { 515 529 callback(Error::QuotaExceeded); 516 530 return; 517 531 } 518 532 519 m_ engine->requestSpace(m_origin,spaceRequired, [callback = WTFMove(callback)](auto decision) mutable {533 m_quotaManager->requestSpace(spaceRequired, [callback = WTFMove(callback)](auto decision) mutable { 520 534 switch (decision) { 521 535 case WebCore::StorageQuotaManager::Decision::Deny: … … 535 549 m_size += recordInformation.size; 536 550 m_size -= previousRecordSize; 551 updateSizeFile(); 537 552 538 553 if (!shouldPersist()) { … … 542 557 } 543 558 544 m_storage->store(Cache::encode(recordInformation, record), { }, [ this, protectedThis = makeRef(*this),protectedStorage = makeRef(*m_storage), callback = WTFMove(callback)](int error) mutable {559 m_storage->store(Cache::encode(recordInformation, record), { }, [protectedStorage = makeRef(*m_storage), callback = WTFMove(callback)](int error) mutable { 545 560 if (error) { 546 561 RELEASE_LOG_ERROR(CacheStorage, "Caches::writeRecord failed with error %d", error); … … 548 563 return; 549 564 } 550 updateSizeFile([callback = WTFMove(callback)]() mutable { 551 callback(WTF::nullopt); 552 }); 565 callback(WTF::nullopt); 553 566 }); 554 567 } … … 593 606 ASSERT(m_size >= record.size); 594 607 m_size -= record.size; 595 updateSizeFile( [] { });608 updateSizeFile(); 596 609 597 610 removeCacheEntry(record.key); … … 607 620 } 608 621 m_storage->remove(key); 622 } 623 624 void Caches::resetSpaceUsed() 625 { 626 m_size = 0; 627 updateSizeFile(); 628 629 if (m_quotaManager) { 630 m_quotaManager->removeUser(*this); 631 m_quotaManager->addUser(*this); 632 } 609 633 } 610 634 -
trunk/Source/WebKit/NetworkProcess/cache/CacheStorageEngineCaches.h
r252805 r252839 29 29 #include "NetworkCacheStorage.h" 30 30 #include <WebCore/ClientOrigin.h> 31 #include <WebCore/StorageQuotaUser.h> 31 32 #include <wtf/CompletionHandler.h> 32 33 #include <wtf/Deque.h> … … 42 43 class Engine; 43 44 44 class Caches final : public RefCounted<Caches> {45 class Caches final : public RefCounted<Caches>, private WebCore::StorageQuotaUser { 45 46 public: 46 static String cachesSizeFilename(const String& cachesRootsPath);47 static Ref<Caches> create(Engine&, WebCore::ClientOrigin&&, String&& rootPath );47 static String cachesSizeFilename(const String&); 48 static Ref<Caches> create(Engine&, WebCore::ClientOrigin&&, String&& rootPath, WebCore::StorageQuotaManager&); 48 49 ~Caches(); 49 50 … … 79 80 void clear(WTF::CompletionHandler<void()>&&); 80 81 void clearMemoryRepresentation(); 82 void resetSpaceUsed(); 81 83 82 84 uint64_t storageSize() const; 83 void updateSizeFile(CompletionHandler<void()>&&);84 85 85 86 private: 86 Caches(Engine&, WebCore::ClientOrigin&&, String&& rootPath); 87 Caches(Engine&, WebCore::ClientOrigin&&, String&& rootPath, WebCore::StorageQuotaManager&); 88 89 // StorageQuotaUser API. 90 uint64_t spaceUsed() const final { return m_size; } 87 91 88 92 void initializeSize(); 89 93 void readCachesFromDisk(WTF::Function<void(Expected<Vector<Cache>, WebCore::DOMCacheEngine::Error>&&)>&&); 90 94 void writeCachesToDisk(WebCore::DOMCacheEngine::CompletionCallback&&); 95 96 void whenInitialized(CompletionHandler<void()>&&) final; 91 97 92 98 void storeOrigin(WebCore::DOMCacheEngine::CompletionCallback&&); … … 100 106 101 107 bool hasActiveCache() const; 108 109 void updateSizeFile(); 102 110 103 111 bool m_isInitialized { false }; … … 115 123 bool m_isWritingCachesToDisk { false }; 116 124 Deque<CompletionHandler<void(Optional<WebCore::DOMCacheEngine::Error>)>> m_pendingWritingCachesToDiskCallbacks; 125 WeakPtr<WebCore::StorageQuotaManager> m_quotaManager; 117 126 }; 118 127 -
trunk/Source/WebKit/Shared/WebsiteDataStoreParameters.cpp
r252805 r252839 55 55 56 56 encoder << localStorageDirectory << localStorageDirectoryExtensionHandle; 57 58 encoder << cacheStorageDirectory << cacheStorageDirectoryExtensionHandle;59 57 60 58 encoder << perOriginStorageQuota; … … 144 142 parameters.localStorageDirectoryExtensionHandle = WTFMove(*localStorageDirectoryExtensionHandle); 145 143 146 Optional<String> cacheStorageDirectory;147 decoder >> cacheStorageDirectory;148 if (!cacheStorageDirectory)149 return WTF::nullopt;150 parameters.cacheStorageDirectory = WTFMove(*cacheStorageDirectory);151 152 Optional<SandboxExtension::Handle> cacheStorageDirectoryExtensionHandle;153 decoder >> cacheStorageDirectoryExtensionHandle;154 if (!cacheStorageDirectoryExtensionHandle)155 return WTF::nullopt;156 parameters.cacheStorageDirectoryExtensionHandle = WTFMove(*cacheStorageDirectoryExtensionHandle);157 158 144 Optional<uint64_t> perOriginStorageQuota; 159 145 decoder >> perOriginStorageQuota; -
trunk/Source/WebKit/Shared/WebsiteDataStoreParameters.h
r252805 r252839 72 72 SandboxExtension::Handle localStorageDirectoryExtensionHandle; 73 73 74 String cacheStorageDirectory;75 SandboxExtension::Handle cacheStorageDirectoryExtensionHandle;76 77 74 uint64_t perOriginStorageQuota { WebCore::StorageQuotaManager::defaultQuota() }; 78 75 uint64_t perThirdPartyOriginStorageQuota { WebCore::StorageQuotaManager::defaultThirdPartyQuota() }; -
trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
r252805 r252839 687 687 WebKit::toImpl(dataStoreRef)->setCacheModelSynchronouslyForTesting(WebKit::toCacheModel(cacheModel)); 688 688 } 689 690 void WKWebsiteDataStoreResetQuota(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreResetQuotaCallback callback)691 {692 WebKit::toImpl(dataStoreRef)->resetQuota([context, callback] {693 if (callback)694 callback(context);695 });696 } -
trunk/Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h
r252805 r252839 156 156 WK_EXPORT void WKWebsiteDataStoreSetCacheModelSynchronouslyForTesting(WKWebsiteDataStoreRef dataStoreRef, WKCacheModel cacheModel); 157 157 158 typedef void (*WKWebsiteDataStoreResetQuotaCallback)(void* functionContext);159 WK_EXPORT void WKWebsiteDataStoreResetQuota(WKWebsiteDataStoreRef dataStoreRef, void* context, WKWebsiteDataStoreResetQuotaCallback callback);160 161 158 #ifdef __cplusplus 162 159 } -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp
r252805 r252839 1368 1368 } 1369 1369 1370 void NetworkProcessProxy::resetQuota(PAL::SessionID sessionID, CompletionHandler<void()>&& completionHandler)1371 {1372 sendWithAsyncReply(Messages::NetworkProcess::ResetQuota(sessionID), WTFMove(completionHandler));1373 }1374 1375 1370 } // namespace WebKit 1376 1371 -
trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h
r252805 r252839 57 57 class SecurityOrigin; 58 58 struct SecurityOriginData; 59 struct ClientOrigin;60 59 } 61 60 … … 198 197 void unregisterSchemeForLegacyCustomProtocol(const String&); 199 198 200 void resetQuota(PAL::SessionID, CompletionHandler<void()>&&);201 202 199 private: 203 200 // AuxiliaryProcessProxy -
trunk/Source/WebKit/UIProcess/WebProcessPool.cpp
r252819 r252839 552 552 SandboxExtension::createHandleForReadWriteDirectory(localStorageDirectory, parameters.defaultDataStoreParameters.localStorageDirectoryExtensionHandle); 553 553 554 auto cacheStorageDirectory = m_websiteDataStore ? m_websiteDataStore->cacheStorageDirectory() : nullString();555 if (!cacheStorageDirectory.isEmpty()) {556 SandboxExtension::createHandleForReadWriteDirectory(cacheStorageDirectory, parameters.defaultDataStoreParameters.cacheStorageDirectoryExtensionHandle);557 parameters.defaultDataStoreParameters.cacheStorageDirectory = WTFMove(cacheStorageDirectory);558 }559 560 554 if (m_websiteDataStore) 561 555 parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory = m_websiteDataStore->resolvedResourceLoadStatisticsDirectory(); -
trunk/Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm
r252805 r252839 192 192 SandboxExtension::createHandleForReadWriteDirectory(parameters.localStorageDirectory, parameters.localStorageDirectoryExtensionHandle); 193 193 194 parameters.cacheStorageDirectory = cacheStorageDirectory();195 if (!parameters.cacheStorageDirectory.isEmpty())196 SandboxExtension::createHandleForReadWriteDirectory(parameters.cacheStorageDirectory, parameters.cacheStorageDirectoryExtensionHandle);197 198 194 parameters.perOriginStorageQuota = perOriginStorageQuota(); 199 195 parameters.perThirdPartyOriginStorageQuota = perThirdPartyOriginStorageQuota(); -
trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
r252805 r252839 2084 2084 } 2085 2085 2086 auto cacheStorageDirectory = this->cacheStorageDirectory();2087 if (!cacheStorageDirectory.isEmpty()) {2088 SandboxExtension::createHandleForReadWriteDirectory(cacheStorageDirectory, parameters.cacheStorageDirectoryExtensionHandle);2089 parameters.cacheStorageDirectory = cacheStorageDirectory;2090 }2091 2092 2086 #if ENABLE(INDEXED_DATABASE) 2093 2087 parameters.indexedDatabaseDirectory = resolvedIndexedDatabaseDirectory(); … … 2176 2170 } 2177 2171 2178 void WebsiteDataStore::resetQuota(CompletionHandler<void()>&& completionHandler)2179 {2180 auto callbackAggregator = CallbackAggregator::create(WTFMove(completionHandler));2181 for (auto& processPool : processPools()) {2182 if (auto* process = processPool->networkProcess())2183 process->resetQuota(m_sessionID, [callbackAggregator = callbackAggregator.copyRef()] { });2184 }2185 }2186 2187 2172 #if !PLATFORM(COCOA) 2188 2173 WTF::String WebsiteDataStore::defaultMediaCacheDirectory() -
trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
r252805 r252839 292 292 static WTF::String defaultDeviceIdHashSaltsStorageDirectory(); 293 293 static WTF::String defaultJavaScriptConfigurationDirectory(); 294 295 void resetQuota(CompletionHandler<void()>&&); 296 294 297 295 private: 298 296 void fetchDataAndApply(OptionSet<WebsiteDataType>, OptionSet<WebsiteDataFetchOption>, RefPtr<WorkQueue>&&, Function<void(Vector<WebsiteDataRecord>)>&& apply); -
trunk/Tools/ChangeLog
r252834 r252839 1 2019-11-23 Commit Queue <commit-queue@webkit.org> 2 3 Unreviewed, rolling out r252805. 4 https://bugs.webkit.org/show_bug.cgi?id=204553 5 6 Caused test failures and ASan crashes (Requested by ap on 7 #webkit). 8 9 Reverted changeset: 10 11 "Cross-thread version StorageQuotaManager" 12 https://bugs.webkit.org/show_bug.cgi?id=203971 13 https://trac.webkit.org/changeset/252805 14 1 15 2019-11-23 Per Arne Vollan <pvollan@apple.com> 2 16 -
trunk/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
r252813 r252839 739 739 93AF4ECE1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */; }; 740 740 93AF4ED11506F130007FD57E /* lots-of-images.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93AF4ECF1506F123007FD57E /* lots-of-images.html */; }; 741 93B62054234EA62C00D49B97 /* StorageQuotaManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */; }; 741 742 93CFA8671CEB9E38000565A8 /* autofocused-text-input.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93CFA8661CEB9DE1000565A8 /* autofocused-text-input.html */; }; 742 743 93D119FC22C680F7009BE3C7 /* localstorage-open-window-private.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 93D119FB22C57112009BE3C7 /* localstorage-open-window-private.html */; }; … … 1143 1144 dstSubfolderSpec = 7; 1144 1145 files = ( 1146 CD8394DF232AF7C000149495 /* media-loading.html in Copy Resources */, 1145 1147 55A817FF2181021A0004A39A /* 100x100-red.tga in Copy Resources */, 1146 1148 1A9E52C913E65EF4006917F5 /* 18-characters.html in Copy Resources */, … … 1375 1377 AD57AC221DA7466E00FF1BDE /* many-iframes.html in Copy Resources */, 1376 1378 7772ECE122FE06C60009A799 /* many-same-origin-iframes.html in Copy Resources */, 1377 CD8394DF232AF7C000149495 /* media-loading.html in Copy Resources */,1378 1379 CDA3159A1ED548F1009F60D3 /* MediaPlaybackSleepAssertion.html in Copy Resources */, 1379 1380 CDC9442F1EF205D60059C3C4 /* mediastreamtrack-detached.html in Copy Resources */, … … 2149 2150 93AF4ECD1506F064007FD57E /* NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NewFirstVisuallyNonEmptyLayoutForImages_Bundle.cpp; sourceTree = "<group>"; }; 2150 2151 93AF4ECF1506F123007FD57E /* lots-of-images.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "lots-of-images.html"; sourceTree = "<group>"; }; 2152 93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StorageQuotaManager.cpp; sourceTree = "<group>"; }; 2151 2153 93CFA8661CEB9DE1000565A8 /* autofocused-text-input.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "autofocused-text-input.html"; sourceTree = "<group>"; }; 2152 2154 93CFA8681CEBCFED000565A8 /* CandidateTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CandidateTests.mm; sourceTree = "<group>"; }; … … 3126 3128 A17991891E1CA24100A505ED /* SharedBufferTest.cpp */, 3127 3129 A179918A1E1CA24100A505ED /* SharedBufferTest.h */, 3130 93B62053234EA32B00D49B97 /* StorageQuotaManager.cpp */, 3128 3131 ECA680CD1E68CC0900731D20 /* StringUtilities.mm */, 3129 3132 CE4D5DE51F6743BA0072CFC6 /* StringWithDirection.cpp */, … … 3853 3856 AD57AC1D1DA7463800FF1BDE /* many-iframes.html */, 3854 3857 7772ECE022FE05E10009A799 /* many-same-origin-iframes.html */, 3855 CD8394DE232AF15E00149495 /* media-loading.html */,3856 3858 CDC9442B1EF1FBD20059C3C4 /* mediastreamtrack-detached.html */, 3857 3859 51CD1C711B38D48400142CA5 /* modal-alerts-in-new-about-blank-window.html */, … … 3885 3887 1C2B81841C8924A200A5529F /* webfont.html */, 3886 3888 468F2F932368DAA700F4B864 /* window-open-then-document-open.html */, 3889 CD8394DE232AF15E00149495 /* media-loading.html */, 3887 3890 ); 3888 3891 name = Resources; … … 4866 4869 CDC0932E21C993440030C4B0 /* StopSuspendResumeAllMedia.mm in Sources */, 4867 4870 414AD6862285D1C000777F2D /* StorageQuota.mm in Sources */, 4871 93B62054234EA62C00D49B97 /* StorageQuotaManager.cpp in Sources */, 4868 4872 515BE1711D428E4B00DD7C68 /* StoreBlobThenDelete.mm in Sources */, 4869 4873 7CCE7ED01A411A7E00447C4C /* StringByEvaluatingJavaScriptFromString.mm in Sources */, -
trunk/Tools/WebKitTestRunner/TestController.cpp
r252805 r252839 982 982 clearDOMCaches(); 983 983 984 resetQuota();985 986 984 WKContextSetAllowsAnySSLCertificateForServiceWorkerTesting(platformContext(), true); 987 985 … … 3145 3143 } 3146 3144 3147 void TestController::resetQuota()3148 {3149 StorageVoidCallbackContext context(*this);3150 WKWebsiteDataStoreResetQuota(TestController::websiteDataStore(), &context, StorageVoidCallback);3151 runUntil(context.done, noTimeout);3152 }3153 3154 3145 struct FetchCacheOriginsCallbackContext { 3155 3146 FetchCacheOriginsCallbackContext(TestController& controller, WKStringRef origin) -
trunk/Tools/WebKitTestRunner/TestController.h
r252805 r252839 270 270 void terminateServiceWorkerProcess(); 271 271 272 void resetQuota();273 274 272 void removeAllSessionCredentials(); 275 273
Note: See TracChangeset
for help on using the changeset viewer.