Bug 1833854 - Part 4: Move all code that deals with maintaining invariants into a...
[gecko.git] / dom / quota / QuotaManager.h
blob380a60c8657e274f8e6f12022561a12031707ddb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_quota_quotamanager_h__
8 #define mozilla_dom_quota_quotamanager_h__
10 #include <cstdint>
11 #include <utility>
12 #include "Client.h"
13 #include "ErrorList.h"
14 #include "mozilla/AlreadyAddRefed.h"
15 #include "mozilla/Assertions.h"
16 #include "mozilla/InitializedOnce.h"
17 #include "mozilla/MozPromise.h"
18 #include "mozilla/Mutex.h"
19 #include "mozilla/RefPtr.h"
20 #include "mozilla/Result.h"
21 #include "mozilla/dom/Nullable.h"
22 #include "mozilla/dom/ipc/IdType.h"
23 #include "mozilla/dom/quota/Assertions.h"
24 #include "mozilla/dom/quota/CommonMetadata.h"
25 #include "mozilla/dom/quota/ForwardDecls.h"
26 #include "mozilla/dom/quota/InitializationTypes.h"
27 #include "mozilla/dom/quota/PersistenceType.h"
28 #include "mozilla/dom/quota/QuotaCommon.h"
29 #include "nsCOMPtr.h"
30 #include "nsClassHashtable.h"
31 #include "nsTHashMap.h"
32 #include "nsDebug.h"
33 #include "nsHashKeys.h"
34 #include "nsISupports.h"
35 #include "nsStringFwd.h"
36 #include "nsTArray.h"
37 #include "nsTStringRepr.h"
38 #include "nscore.h"
39 #include "prenv.h"
41 #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
43 class mozIStorageConnection;
44 class nsIEventTarget;
45 class nsIFile;
46 class nsIPrincipal;
47 class nsIRunnable;
48 class nsIThread;
49 class nsITimer;
50 class nsPIDOMWindowOuter;
52 namespace mozilla {
54 class OriginAttributes;
56 namespace ipc {
58 class PrincipalInfo;
60 } // namespace ipc
62 } // namespace mozilla
64 namespace mozilla::dom::quota {
66 class CanonicalQuotaObject;
67 class ClientUsageArray;
68 class ClientDirectoryLock;
69 class DirectoryLockImpl;
70 class GroupInfo;
71 class GroupInfoPair;
72 class OriginDirectoryLock;
73 class OriginInfo;
74 class OriginScope;
75 class QuotaObject;
76 class UniversalDirectoryLock;
78 class QuotaManager final : public BackgroundThreadObject {
79 friend class CanonicalQuotaObject;
80 friend class DirectoryLockImpl;
81 friend class GroupInfo;
82 friend class OriginInfo;
84 using PrincipalInfo = mozilla::ipc::PrincipalInfo;
85 using DirectoryLockTable =
86 nsClassHashtable<nsCStringHashKey, nsTArray<NotNull<DirectoryLockImpl*>>>;
88 class Observer;
90 public:
91 QuotaManager(const nsAString& aBasePath, const nsAString& aStorageName);
93 NS_INLINE_DECL_REFCOUNTING(QuotaManager)
95 static nsresult Initialize();
97 static bool IsRunningXPCShellTests() {
98 static bool kRunningXPCShellTests =
99 !!PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
100 return kRunningXPCShellTests;
103 static bool IsRunningGTests() {
104 static bool kRunningGTests = !!PR_GetEnv("MOZ_RUN_GTEST");
105 return kRunningGTests;
108 static const char kReplaceChars[];
109 static const char16_t kReplaceChars16[];
111 static Result<MovingNotNull<RefPtr<QuotaManager>>, nsresult> GetOrCreate();
113 static Result<Ok, nsresult> EnsureCreated();
115 // Returns a non-owning reference.
116 static QuotaManager* Get();
118 // Use only in gtests!
119 static nsIObserver* GetObserver();
121 // Returns true if we've begun the shutdown process.
122 static bool IsShuttingDown();
124 static void ShutdownInstance();
126 // Use only in gtests!
127 static void Reset();
129 static bool IsOSMetadata(const nsAString& aFileName);
131 static bool IsDotFile(const nsAString& aFileName);
133 bool IsOriginInitialized(const nsACString& aOrigin) const {
134 AssertIsOnIOThread();
136 return mInitializedOrigins.Contains(aOrigin);
139 bool IsTemporaryStorageInitialized() const {
140 AssertIsOnIOThread();
142 return mTemporaryStorageInitialized;
146 * For initialization of an origin where the directory already exists. This is
147 * used by EnsureTemporaryStorageIsInitialized/InitializeRepository once it
148 * has tallied origin usage by calling each of the QuotaClient InitOrigin
149 * methods.
151 void InitQuotaForOrigin(const FullOriginMetadata& aFullOriginMetadata,
152 const ClientUsageArray& aClientUsages,
153 uint64_t aUsageBytes);
156 * For use in special-cases like LSNG where we need to be able to know that
157 * there is no data stored for an origin. LSNG knows that there is 0 usage for
158 * its storage of an origin and wants to make sure there is a QuotaObject
159 * tracking this. This method will create a non-persisted, 0-usage,
160 * mDirectoryExists=false OriginInfo if there isn't already an OriginInfo. If
161 * an OriginInfo already exists, it will be left as-is, because that implies a
162 * different client has usages for the origin (and there's no need to add
163 * LSNG's 0 usage to the QuotaObject).
165 void EnsureQuotaForOrigin(const OriginMetadata& aOriginMetadata);
168 * For use when creating an origin directory. It's possible that origin usage
169 * is already being tracked due to a call to EnsureQuotaForOrigin, and in that
170 * case we need to update the existing OriginInfo rather than create a new
171 * one.
173 * @return last access time of the origin.
175 int64_t NoteOriginDirectoryCreated(const OriginMetadata& aOriginMetadata,
176 bool aPersisted);
178 // XXX clients can use QuotaObject instead of calling this method directly.
179 void DecreaseUsageForClient(const ClientMetadata& aClientMetadata,
180 int64_t aSize);
182 void ResetUsageForClient(const ClientMetadata& aClientMetadata);
184 UsageInfo GetUsageForClient(PersistenceType aPersistenceType,
185 const OriginMetadata& aOriginMetadata,
186 Client::Type aClientType);
188 void UpdateOriginAccessTime(PersistenceType aPersistenceType,
189 const OriginMetadata& aOriginMetadata);
191 void RemoveQuota();
193 void RemoveQuotaForRepository(PersistenceType aPersistenceType) {
194 MutexAutoLock lock(mQuotaMutex);
195 LockedRemoveQuotaForRepository(aPersistenceType);
198 void RemoveQuotaForOrigin(PersistenceType aPersistenceType,
199 const OriginMetadata& aOriginMetadata) {
200 MutexAutoLock lock(mQuotaMutex);
201 LockedRemoveQuotaForOrigin(aOriginMetadata);
204 nsresult LoadQuota();
206 void UnloadQuota();
208 already_AddRefed<QuotaObject> GetQuotaObject(
209 PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
210 Client::Type aClientType, nsIFile* aFile, int64_t aFileSize = -1,
211 int64_t* aFileSizeOut = nullptr);
213 already_AddRefed<QuotaObject> GetQuotaObject(
214 PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
215 Client::Type aClientType, const nsAString& aPath, int64_t aFileSize = -1,
216 int64_t* aFileSizeOut = nullptr);
218 already_AddRefed<QuotaObject> GetQuotaObject(const int64_t aDirectoryLockId,
219 const nsAString& aPath);
221 Nullable<bool> OriginPersisted(const OriginMetadata& aOriginMetadata);
223 void PersistOrigin(const OriginMetadata& aOriginMetadata);
225 using DirectoryLockIdTableArray =
226 AutoTArray<Client::DirectoryLockIdTable, Client::TYPE_MAX>;
227 void AbortOperationsForLocks(const DirectoryLockIdTableArray& aLockIds);
229 // Called when a process is being shot down. Aborts any running operations
230 // for the given process.
231 void AbortOperationsForProcess(ContentParentId aContentParentId);
233 Result<nsCOMPtr<nsIFile>, nsresult> GetOriginDirectory(
234 const OriginMetadata& aOriginMetadata) const;
236 nsresult RestoreDirectoryMetadata2(nsIFile* aDirectory);
238 // XXX Remove aPersistenceType argument once the persistence type is stored
239 // in the metadata file.
240 Result<FullOriginMetadata, nsresult> LoadFullOriginMetadata(
241 nsIFile* aDirectory, PersistenceType aPersistenceType);
243 Result<FullOriginMetadata, nsresult> LoadFullOriginMetadataWithRestore(
244 nsIFile* aDirectory);
246 Result<OriginMetadata, nsresult> GetOriginMetadata(nsIFile* aDirectory);
248 // This is the main entry point into the QuotaManager API.
249 // Any storage API implementation (quota client) that participates in
250 // centralized quota and storage handling should call this method to get
251 // a directory lock which will protect client's files from being deleted
252 // while they are still in use.
253 // After a lock is acquired, client is notified via the open listener's
254 // method DirectoryLockAcquired. If the lock couldn't be acquired, client
255 // gets DirectoryLockFailed notification.
256 // A lock is a reference counted object and at the time DirectoryLockAcquired
257 // is called, quota manager holds just one strong reference to it which is
258 // then immediatelly cleared by quota manager. So it's up to client to add
259 // a new reference in order to keep the lock alive.
260 // Unlocking is simply done by dropping all references to the lock object.
261 // In other words, protection which the lock represents dies with the lock
262 // object itself.
263 RefPtr<ClientDirectoryLock> CreateDirectoryLock(
264 PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
265 Client::Type aClientType, bool aExclusive);
267 // XXX RemoveMe once bug 1170279 gets fixed.
268 RefPtr<UniversalDirectoryLock> CreateDirectoryLockInternal(
269 const Nullable<PersistenceType>& aPersistenceType,
270 const OriginScope& aOriginScope,
271 const Nullable<Client::Type>& aClientType, bool aExclusive);
273 // Collect inactive and the least recently used origins.
274 uint64_t CollectOriginsForEviction(
275 uint64_t aMinSizeToBeFreed,
276 nsTArray<RefPtr<OriginDirectoryLock>>& aLocks);
279 * Helper method to invoke the provided predicate on all "pending" OriginInfo
280 * instances. These are origins for which the origin directory has not yet
281 * been created but for which quota is already being tracked. This happens,
282 * for example, for the LocalStorage client where an origin that previously
283 * was not using LocalStorage can start issuing writes which it buffers until
284 * eventually flushing them. We defer creating the origin directory for as
285 * long as possible in that case, so the directory won't exist. Logic that
286 * would otherwise only consult the filesystem also needs to use this method.
288 template <typename P>
289 void CollectPendingOriginsForListing(P aPredicate);
291 bool IsStorageInitialized() const {
292 AssertIsOnIOThread();
293 return static_cast<bool>(mStorageConnection);
296 void AssertStorageIsInitialized() const
297 #ifdef DEBUG
299 #else
302 #endif
304 nsresult EnsureStorageIsInitialized();
306 // Returns a pair of an nsIFile object referring to the directory, and a bool
307 // indicating whether the directory was newly created.
308 Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
309 EnsurePersistentOriginIsInitialized(const OriginMetadata& aOriginMetadata);
311 // Returns a pair of an nsIFile object referring to the directory, and a bool
312 // indicating whether the directory was newly created.
313 Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
314 EnsureTemporaryOriginIsInitialized(PersistenceType aPersistenceType,
315 const OriginMetadata& aOriginMetadata);
317 nsresult EnsureTemporaryStorageIsInitialized();
319 RefPtr<BoolPromise> ClearPrivateRepository();
321 RefPtr<BoolPromise> ShutdownStorage();
323 void ShutdownStorageInternal();
325 // Returns a bool indicating whether the directory was newly created.
326 Result<bool, nsresult> EnsureOriginDirectory(nsIFile& aDirectory);
328 nsresult AboutToClearOrigins(
329 const Nullable<PersistenceType>& aPersistenceType,
330 const OriginScope& aOriginScope,
331 const Nullable<Client::Type>& aClientType);
333 void OriginClearCompleted(PersistenceType aPersistenceType,
334 const nsACString& aOrigin,
335 const Nullable<Client::Type>& aClientType);
337 void RepositoryClearCompleted(PersistenceType aPersistenceType);
339 void StartIdleMaintenance() {
340 AssertIsOnOwningThread();
342 for (const auto& client : *mClients) {
343 client->StartIdleMaintenance();
347 void StopIdleMaintenance() {
348 AssertIsOnOwningThread();
350 for (const auto& client : *mClients) {
351 client->StopIdleMaintenance();
355 void AssertCurrentThreadOwnsQuotaMutex() {
356 mQuotaMutex.AssertCurrentThreadOwns();
359 nsIThread* IOThread() { return mIOThread->get(); }
361 Client* GetClient(Client::Type aClientType);
363 const AutoTArray<Client::Type, Client::TYPE_MAX>& AllClientTypes();
365 const nsString& GetBasePath() const { return mBasePath; }
367 const nsString& GetStorageName() const { return mStorageName; }
369 const nsString& GetStoragePath() const { return *mStoragePath; }
371 const nsString& GetStoragePath(PersistenceType aPersistenceType) const {
372 if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
373 return *mPermanentStoragePath;
376 if (aPersistenceType == PERSISTENCE_TYPE_TEMPORARY) {
377 return *mTemporaryStoragePath;
380 if (aPersistenceType == PERSISTENCE_TYPE_DEFAULT) {
381 return *mDefaultStoragePath;
384 MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_PRIVATE);
386 return *mPrivateStoragePath;
389 uint64_t GetGroupLimit() const;
391 std::pair<uint64_t, uint64_t> GetUsageAndLimitForEstimate(
392 const OriginMetadata& aOriginMetadata);
394 uint64_t GetOriginUsage(const PrincipalMetadata& aPrincipalMetadata);
396 Maybe<FullOriginMetadata> GetFullOriginMetadata(
397 const OriginMetadata& aOriginMetadata);
399 void NotifyStoragePressure(uint64_t aUsage);
401 // Record a quota client shutdown step, if shutting down.
402 // Assumes that the QuotaManager singleton is alive.
403 static void MaybeRecordQuotaClientShutdownStep(
404 const Client::Type aClientType, const nsACString& aStepDescription);
406 // Record a quota client shutdown step, if shutting down.
407 // Checks if the QuotaManager singleton is alive.
408 static void SafeMaybeRecordQuotaClientShutdownStep(
409 Client::Type aClientType, const nsACString& aStepDescription);
411 // Record a quota manager shutdown step, use only if shutdown is active.
412 void RecordQuotaManagerShutdownStep(const nsACString& aStepDescription);
414 // Record a quota manager shutdown step, if shutting down.
415 void MaybeRecordQuotaManagerShutdownStep(const nsACString& aStepDescription);
417 template <typename F>
418 void MaybeRecordQuotaManagerShutdownStepWith(F&& aFunc);
420 static void GetStorageId(PersistenceType aPersistenceType,
421 const nsACString& aOrigin, Client::Type aClientType,
422 nsACString& aDatabaseId);
424 static bool IsPrincipalInfoValid(const PrincipalInfo& aPrincipalInfo);
426 Result<PrincipalMetadata, nsresult> GetInfoFromValidatedPrincipalInfo(
427 const PrincipalInfo& aPrincipalInfo);
429 static nsAutoCString GetOriginFromValidatedPrincipalInfo(
430 const PrincipalInfo& aPrincipalInfo);
432 static Result<PrincipalMetadata, nsresult> GetInfoFromPrincipal(
433 nsIPrincipal* aPrincipal);
435 static Result<PrincipalMetadata, nsresult> GetInfoFromWindow(
436 nsPIDOMWindowOuter* aWindow);
438 static Result<nsAutoCString, nsresult> GetOriginFromPrincipal(
439 nsIPrincipal* aPrincipal);
441 static Result<nsAutoCString, nsresult> GetOriginFromWindow(
442 nsPIDOMWindowOuter* aWindow);
444 static nsLiteralCString GetOriginForChrome();
446 static PrincipalMetadata GetInfoForChrome();
448 static bool IsOriginInternal(const nsACString& aOrigin);
450 static bool AreOriginsEqualOnDisk(const nsACString& aOrigin1,
451 const nsACString& aOrigin2);
453 static Result<PrincipalInfo, nsresult> ParseOrigin(const nsACString& aOrigin);
455 static void InvalidateQuotaCache();
457 private:
458 virtual ~QuotaManager();
460 nsresult Init();
462 void Shutdown();
464 void RegisterDirectoryLock(DirectoryLockImpl& aLock);
466 void UnregisterDirectoryLock(DirectoryLockImpl& aLock);
468 void AddPendingDirectoryLock(DirectoryLockImpl& aLock);
470 void RemovePendingDirectoryLock(DirectoryLockImpl& aLock);
472 uint64_t LockedCollectOriginsForEviction(
473 uint64_t aMinSizeToBeFreed,
474 nsTArray<RefPtr<OriginDirectoryLock>>& aLocks);
476 void LockedRemoveQuotaForRepository(PersistenceType aPersistenceType);
478 void LockedRemoveQuotaForOrigin(const OriginMetadata& aOriginMetadata);
480 already_AddRefed<GroupInfo> LockedGetOrCreateGroupInfo(
481 PersistenceType aPersistenceType, const nsACString& aSuffix,
482 const nsACString& aGroup);
484 already_AddRefed<OriginInfo> LockedGetOriginInfo(
485 PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata);
487 nsresult UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
488 nsIFile* aIndexedDBDir);
490 nsresult UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
491 nsIFile* aPersistentStorageDir);
493 nsresult MaybeUpgradeToDefaultStorageDirectory(nsIFile& aStorageFile);
495 template <typename Helper>
496 nsresult UpgradeStorage(const int32_t aOldVersion, const int32_t aNewVersion,
497 mozIStorageConnection* aConnection);
499 nsresult UpgradeStorageFrom0_0To1_0(mozIStorageConnection* aConnection);
501 nsresult UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection);
503 nsresult UpgradeStorageFrom2_0To2_1(mozIStorageConnection* aConnection);
505 nsresult UpgradeStorageFrom2_1To2_2(mozIStorageConnection* aConnection);
507 nsresult UpgradeStorageFrom2_2To2_3(mozIStorageConnection* aConnection);
509 nsresult MaybeCreateOrUpgradeStorage(mozIStorageConnection& aConnection);
511 OkOrErr MaybeRemoveLocalStorageArchiveTmpFile();
513 nsresult MaybeRemoveLocalStorageDataAndArchive(nsIFile& aLsArchiveFile);
515 nsresult MaybeRemoveLocalStorageDirectories();
517 Result<Ok, nsresult> CopyLocalStorageArchiveFromWebAppsStore(
518 nsIFile& aLsArchiveFile) const;
520 Result<nsCOMPtr<mozIStorageConnection>, nsresult>
521 CreateLocalStorageArchiveConnection(nsIFile& aLsArchiveFile) const;
523 Result<nsCOMPtr<mozIStorageConnection>, nsresult>
524 RecopyLocalStorageArchiveFromWebAppsStore(nsIFile& aLsArchiveFile);
526 Result<nsCOMPtr<mozIStorageConnection>, nsresult>
527 DowngradeLocalStorageArchive(nsIFile& aLsArchiveFile);
529 Result<nsCOMPtr<mozIStorageConnection>, nsresult>
530 UpgradeLocalStorageArchiveFromLessThan4To4(nsIFile& aLsArchiveFile);
533 nsresult UpgradeLocalStorageArchiveFrom4To5();
536 Result<Ok, nsresult> MaybeCreateOrUpgradeLocalStorageArchive(
537 nsIFile& aLsArchiveFile);
539 Result<Ok, nsresult> CreateEmptyLocalStorageArchive(
540 nsIFile& aLsArchiveFile) const;
542 template <typename OriginFunc>
543 nsresult InitializeRepository(PersistenceType aPersistenceType,
544 OriginFunc&& aOriginFunc);
546 nsresult InitializeOrigin(PersistenceType aPersistenceType,
547 const OriginMetadata& aOriginMetadata,
548 int64_t aAccessTime, bool aPersisted,
549 nsIFile* aDirectory);
551 using OriginInfosFlatTraversable =
552 nsTArray<NotNull<RefPtr<const OriginInfo>>>;
554 using OriginInfosNestedTraversable =
555 nsTArray<nsTArray<NotNull<RefPtr<const OriginInfo>>>>;
557 OriginInfosNestedTraversable GetOriginInfosExceedingGroupLimit() const;
559 OriginInfosNestedTraversable GetOriginInfosExceedingGlobalLimit() const;
561 void ClearOrigins(const OriginInfosNestedTraversable& aDoomedOriginInfos);
563 void CleanupTemporaryStorage();
565 void DeleteOriginDirectory(const OriginMetadata& aOriginMetadata);
567 void FinalizeOriginEviction(nsTArray<RefPtr<OriginDirectoryLock>>&& aLocks);
569 Result<Ok, nsresult> ArchiveOrigins(
570 const nsTArray<FullOriginMetadata>& aFullOriginMetadatas);
572 void ReleaseIOThreadObjects() {
573 AssertIsOnIOThread();
575 for (Client::Type type : AllClientTypes()) {
576 (*mClients)[type]->ReleaseIOThreadObjects();
580 DirectoryLockTable& GetDirectoryLockTable(PersistenceType aPersistenceType);
582 bool IsSanitizedOriginValid(const nsACString& aSanitizedOrigin);
584 Result<nsCString, nsresult> EnsureStorageOriginFromOrigin(
585 const nsACString& aOrigin);
587 Result<nsCString, nsresult> GetOriginFromStorageOrigin(
588 const nsACString& aStorageOrigin);
590 int64_t GenerateDirectoryLockId();
592 bool ShutdownStarted() const;
594 void RecordShutdownStep(Maybe<Client::Type> aClientType,
595 const nsACString& aStepDescription);
597 template <typename Func>
598 auto ExecuteInitialization(Initialization aInitialization, Func&& aFunc)
599 -> std::invoke_result_t<Func, const FirstInitializationAttempt<
600 Initialization, StringGenerator>&>;
602 template <typename Func>
603 auto ExecuteInitialization(Initialization aInitialization,
604 const nsACString& aContext, Func&& aFunc)
605 -> std::invoke_result_t<Func, const FirstInitializationAttempt<
606 Initialization, StringGenerator>&>;
608 template <typename Func>
609 auto ExecuteOriginInitialization(const nsACString& aOrigin,
610 const OriginInitialization aInitialization,
611 const nsACString& aContext, Func&& aFunc)
612 -> std::invoke_result_t<Func, const FirstInitializationAttempt<
613 Initialization, StringGenerator>&>;
615 template <typename Iterator>
616 static void MaybeInsertNonPersistedOriginInfos(
617 Iterator aDest, const RefPtr<GroupInfo>& aTemporaryGroupInfo,
618 const RefPtr<GroupInfo>& aDefaultGroupInfo,
619 const RefPtr<GroupInfo>& aPrivateGroupInfo);
621 template <typename Collect, typename Pred>
622 static OriginInfosFlatTraversable CollectLRUOriginInfosUntil(
623 Collect&& aCollect, Pred&& aPred);
625 // Thread on which IO is performed.
626 LazyInitializedOnceNotNull<const nsCOMPtr<nsIThread>> mIOThread;
628 nsCOMPtr<mozIStorageConnection> mStorageConnection;
630 EnumeratedArray<Client::Type, Client::TYPE_MAX, nsCString> mShutdownSteps;
631 LazyInitializedOnce<const TimeStamp> mShutdownStartedAt;
633 // Accesses to mQuotaManagerShutdownSteps must be protected by mQuotaMutex.
634 nsCString mQuotaManagerShutdownSteps;
636 mutable mozilla::Mutex mQuotaMutex MOZ_UNANNOTATED;
638 nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
640 // Maintains a list of directory locks that are queued.
641 nsTArray<RefPtr<DirectoryLockImpl>> mPendingDirectoryLocks;
643 // Maintains a list of directory locks that are acquired or queued. It can be
644 // accessed on the owning (PBackground) thread only.
645 nsTArray<NotNull<DirectoryLockImpl*>> mDirectoryLocks;
647 // Only modifed on the owning thread, but read on multiple threads. Therefore
648 // all modifications (including those on the owning thread) and all reads off
649 // the owning thread must be protected by mQuotaMutex. In other words, only
650 // reads on the owning thread don't have to be protected by mQuotaMutex.
651 nsTHashMap<nsUint64HashKey, NotNull<DirectoryLockImpl*>>
652 mDirectoryLockIdTable;
654 // Directory lock tables that are used to update origin access time.
655 DirectoryLockTable mTemporaryDirectoryLockTable;
656 DirectoryLockTable mDefaultDirectoryLockTable;
657 DirectoryLockTable mPrivateDirectoryLockTable;
659 // A list of all successfully initialized persistent origins. This list isn't
660 // protected by any mutex but it is only ever touched on the IO thread.
661 nsTArray<nsCString> mInitializedOrigins;
663 // A hash table that is used to cache origin parser results for given
664 // sanitized origin strings. This hash table isn't protected by any mutex but
665 // it is only ever touched on the IO thread.
666 nsTHashMap<nsCStringHashKey, bool> mValidOrigins;
668 // These maps are protected by mQuotaMutex.
669 nsTHashMap<nsCStringHashKey, nsCString> mOriginToStorageOriginMap;
670 nsTHashMap<nsCStringHashKey, nsCString> mStorageOriginToOriginMap;
672 // This array is populated at initialization time and then never modified, so
673 // it can be iterated on any thread.
674 LazyInitializedOnce<const AutoTArray<RefPtr<Client>, Client::TYPE_MAX>>
675 mClients;
677 using ClientTypesArray = AutoTArray<Client::Type, Client::TYPE_MAX>;
678 LazyInitializedOnce<const ClientTypesArray> mAllClientTypes;
679 LazyInitializedOnce<const ClientTypesArray> mAllClientTypesExceptLS;
681 // This object isn't protected by any mutex but it is only ever touched on
682 // the IO thread.
683 InitializationInfo mInitializationInfo;
685 const nsString mBasePath;
686 const nsString mStorageName;
687 LazyInitializedOnce<const nsString> mIndexedDBPath;
688 LazyInitializedOnce<const nsString> mStoragePath;
689 LazyInitializedOnce<const nsString> mStorageArchivesPath;
690 LazyInitializedOnce<const nsString> mPermanentStoragePath;
691 LazyInitializedOnce<const nsString> mTemporaryStoragePath;
692 LazyInitializedOnce<const nsString> mDefaultStoragePath;
693 LazyInitializedOnce<const nsString> mPrivateStoragePath;
695 MozPromiseHolder<BoolPromise> mShutdownStoragePromiseHolder;
697 uint64_t mTemporaryStorageLimit;
698 uint64_t mTemporaryStorageUsage;
699 int64_t mNextDirectoryLockId;
700 bool mTemporaryStorageInitialized;
701 bool mCacheUsable;
702 bool mShuttingDownStorage;
705 } // namespace mozilla::dom::quota
707 #endif /* mozilla_dom_quota_quotamanager_h__ */