Bug 1688354 [wpt PR 27298] - Treat 'rem' as an absolute unit for font size, a=testonly
[gecko.git] / dom / quota / QuotaManager.h
blob9dad7942c3025a8d586247d08fff149f19357693
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/Mutex.h"
18 #include "mozilla/RefPtr.h"
19 #include "mozilla/Result.h"
20 #include "mozilla/dom/Nullable.h"
21 #include "mozilla/dom/ipc/IdType.h"
22 #include "mozilla/dom/quota/InitializationTypes.h"
23 #include "mozilla/dom/quota/PersistenceType.h"
24 #include "mozilla/dom/quota/QuotaCommon.h"
25 #include "mozilla/dom/quota/QuotaInfo.h"
26 #include "nsCOMPtr.h"
27 #include "nsClassHashtable.h"
28 #include "nsDataHashtable.h"
29 #include "nsDebug.h"
30 #include "nsHashKeys.h"
31 #include "nsISupports.h"
32 #include "nsStringFwd.h"
33 #include "nsTArray.h"
34 #include "nsTStringRepr.h"
35 #include "nscore.h"
36 #include "prenv.h"
38 #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
40 class mozIStorageConnection;
41 class nsIEventTarget;
42 class nsIFile;
43 class nsIPrincipal;
44 class nsIRunnable;
45 class nsIThread;
46 class nsITimer;
47 class nsPIDOMWindowOuter;
49 namespace mozilla {
51 class OriginAttributes;
53 namespace ipc {
55 class PrincipalInfo;
57 } // namespace ipc
59 } // namespace mozilla
61 namespace mozilla::dom::quota {
63 class ClientUsageArray;
64 class DirectoryLockImpl;
65 class GroupInfo;
66 class GroupInfoPair;
67 class OriginInfo;
68 class OriginScope;
69 class QuotaObject;
71 class NS_NO_VTABLE RefCountedObject {
72 public:
73 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
76 class DirectoryLock : public RefCountedObject {
77 friend class DirectoryLockImpl;
79 public:
80 int64_t Id() const;
82 // 'Get' prefix is to avoid name collisions with the enum
83 PersistenceType GetPersistenceType() const;
85 quota::GroupAndOrigin GroupAndOrigin() const;
87 const nsACString& Origin() const;
89 Client::Type ClientType() const;
91 already_AddRefed<DirectoryLock> Specialize(
92 PersistenceType aPersistenceType,
93 const quota::GroupAndOrigin& aGroupAndOrigin,
94 Client::Type aClientType) const;
96 void Log() const;
98 private:
99 DirectoryLock() = default;
101 ~DirectoryLock() = default;
104 class NS_NO_VTABLE OpenDirectoryListener : public RefCountedObject {
105 public:
106 virtual void DirectoryLockAcquired(DirectoryLock* aLock) = 0;
108 virtual void DirectoryLockFailed() = 0;
110 protected:
111 virtual ~OpenDirectoryListener() = default;
114 struct OriginParams {
115 OriginParams(PersistenceType aPersistenceType, const nsACString& aOrigin)
116 : mOrigin(aOrigin), mPersistenceType(aPersistenceType) {}
118 nsCString mOrigin;
119 PersistenceType mPersistenceType;
122 class QuotaManager final : public BackgroundThreadObject {
123 friend class DirectoryLockImpl;
124 friend class GroupInfo;
125 friend class OriginInfo;
126 friend class QuotaObject;
128 typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
129 typedef nsClassHashtable<nsCStringHashKey,
130 nsTArray<NotNull<DirectoryLockImpl*>>>
131 DirectoryLockTable;
133 class Observer;
135 public:
136 NS_INLINE_DECL_REFCOUNTING(QuotaManager)
138 static nsresult Initialize();
140 static bool IsRunningXPCShellTests() {
141 static bool kRunningXPCShellTests =
142 !!PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
143 return kRunningXPCShellTests;
146 static bool IsRunningGTests() {
147 static bool kRunningGTests = !!PR_GetEnv("MOZ_RUN_GTEST");
148 return kRunningGTests;
151 static const char kReplaceChars[];
153 static void GetOrCreate(nsIRunnable* aCallback,
154 nsIEventTarget* aMainEventTarget = nullptr);
156 // Returns a non-owning reference.
157 static QuotaManager* Get();
159 static QuotaManager& GetRef();
161 // Returns true if we've begun the shutdown process.
162 static bool IsShuttingDown();
164 static void ShutdownInstance();
166 static bool IsOSMetadata(const nsAString& aFileName);
168 static bool IsDotFile(const nsAString& aFileName);
170 bool IsOriginInitialized(const nsACString& aOrigin) const {
171 AssertIsOnIOThread();
173 return mInitializedOrigins.Contains(aOrigin);
176 bool IsTemporaryStorageInitialized() const {
177 AssertIsOnIOThread();
179 return mTemporaryStorageInitialized;
183 * For initialization of an origin where the directory already exists. This is
184 * used by EnsureTemporaryStorageIsInitialized/InitializeRepository once it
185 * has tallied origin usage by calling each of the QuotaClient InitOrigin
186 * methods.
188 void InitQuotaForOrigin(PersistenceType aPersistenceType,
189 const GroupAndOrigin& aGroupAndOrigin,
190 const ClientUsageArray& aClientUsages,
191 uint64_t aUsageBytes, int64_t aAccessTime,
192 bool aPersisted);
195 * For use in special-cases like LSNG where we need to be able to know that
196 * there is no data stored for an origin. LSNG knows that there is 0 usage for
197 * its storage of an origin and wants to make sure there is a QuotaObject
198 * tracking this. This method will create a non-persisted, 0-usage,
199 * mDirectoryExists=false OriginInfo if there isn't already an OriginInfo. If
200 * an OriginInfo already exists, it will be left as-is, because that implies a
201 * different client has usages for the origin (and there's no need to add
202 * LSNG's 0 usage to the QuotaObject).
204 void EnsureQuotaForOrigin(PersistenceType aPersistenceType,
205 const GroupAndOrigin& aGroupAndOrigin);
208 * For use when creating an origin directory. It's possible that origin usage
209 * is already being tracked due to a call to EnsureQuotaForOrigin, and in that
210 * case we need to update the existing OriginInfo rather than create a new
211 * one.
213 void NoteOriginDirectoryCreated(PersistenceType aPersistenceType,
214 const GroupAndOrigin& aGroupAndOrigin,
215 bool aPersisted, int64_t& aTimestamp);
217 // XXX clients can use QuotaObject instead of calling this method directly.
218 void DecreaseUsageForOrigin(PersistenceType aPersistenceType,
219 const GroupAndOrigin& aGroupAndOrigin,
220 Client::Type aClientType, int64_t aSize);
222 void ResetUsageForClient(PersistenceType aPersistenceType,
223 const GroupAndOrigin& aGroupAndOrigin,
224 Client::Type aClientType);
226 UsageInfo GetUsageForClient(PersistenceType aPersistenceType,
227 const GroupAndOrigin& aGroupAndOrigin,
228 Client::Type aClientType);
230 void UpdateOriginAccessTime(PersistenceType aPersistenceType,
231 const GroupAndOrigin& aGroupAndOrigin);
233 void RemoveQuota();
235 void RemoveQuotaForOrigin(PersistenceType aPersistenceType,
236 const GroupAndOrigin& aGroupAndOrigin) {
237 MutexAutoLock lock(mQuotaMutex);
238 LockedRemoveQuotaForOrigin(aPersistenceType, aGroupAndOrigin);
241 nsresult LoadQuota();
243 void UnloadQuota();
245 already_AddRefed<QuotaObject> GetQuotaObject(
246 PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin,
247 Client::Type aClientType, nsIFile* aFile, int64_t aFileSize = -1,
248 int64_t* aFileSizeOut = nullptr);
250 already_AddRefed<QuotaObject> GetQuotaObject(
251 PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin,
252 Client::Type aClientType, const nsAString& aPath, int64_t aFileSize = -1,
253 int64_t* aFileSizeOut = nullptr);
255 already_AddRefed<QuotaObject> GetQuotaObject(const int64_t aDirectoryLockId,
256 const nsAString& aPath);
258 Nullable<bool> OriginPersisted(const GroupAndOrigin& aGroupAndOrigin);
260 void PersistOrigin(const GroupAndOrigin& aGroupAndOrigin);
262 // Called when a process is being shot down. Aborts any running operations
263 // for the given process.
264 void AbortOperationsForProcess(ContentParentId aContentParentId);
266 Result<nsCOMPtr<nsIFile>, nsresult> GetDirectoryForOrigin(
267 PersistenceType aPersistenceType, const nsACString& aASCIIOrigin) const;
269 nsresult RestoreDirectoryMetadata2(nsIFile* aDirectory, bool aPersistent);
271 struct GetDirectoryResult {
272 int64_t mTimestamp;
273 bool mPersisted;
276 struct GetDirectoryResultWithQuotaInfo : GetDirectoryResult {
277 QuotaInfo mQuotaInfo;
280 Result<GetDirectoryResultWithQuotaInfo, nsresult>
281 GetDirectoryMetadataWithQuotaInfo2(nsIFile* aDirectory);
283 Result<GetDirectoryResultWithQuotaInfo, nsresult>
284 GetDirectoryMetadataWithQuotaInfo2WithRestore(nsIFile* aDirectory,
285 bool aPersistent);
287 Result<GetDirectoryResult, nsresult> GetDirectoryMetadata2(
288 nsIFile* aDirectory);
290 Result<GetDirectoryResult, nsresult> GetDirectoryMetadata2WithRestore(
291 nsIFile* aDirectory, bool aPersistent);
293 // This is the main entry point into the QuotaManager API.
294 // Any storage API implementation (quota client) that participates in
295 // centralized quota and storage handling should call this method to get
296 // a directory lock which will protect client's files from being deleted
297 // while they are still in use.
298 // After a lock is acquired, client is notified via the open listener's
299 // method DirectoryLockAcquired. If the lock couldn't be acquired, client
300 // gets DirectoryLockFailed notification.
301 // A lock is a reference counted object and at the time DirectoryLockAcquired
302 // is called, quota manager holds just one strong reference to it which is
303 // then immediatelly cleared by quota manager. So it's up to client to add
304 // a new reference in order to keep the lock alive.
305 // Unlocking is simply done by dropping all references to the lock object.
306 // In other words, protection which the lock represents dies with the lock
307 // object itself.
308 already_AddRefed<DirectoryLock> OpenDirectory(
309 PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin,
310 Client::Type aClientType, bool aExclusive,
311 RefPtr<OpenDirectoryListener> aOpenListener);
313 // XXX RemoveMe once bug 1170279 gets fixed.
314 already_AddRefed<DirectoryLock> OpenDirectoryInternal(
315 const Nullable<PersistenceType>& aPersistenceType,
316 const OriginScope& aOriginScope,
317 const Nullable<Client::Type>& aClientType, bool aExclusive,
318 OpenDirectoryListener* aOpenListener);
320 // Collect inactive and the least recently used origins.
321 uint64_t CollectOriginsForEviction(
322 uint64_t aMinSizeToBeFreed, nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
325 * Helper method to invoke the provided predicate on all "pending" OriginInfo
326 * instances. These are origins for which the origin directory has not yet
327 * been created but for which quota is already being tracked. This happens,
328 * for example, for the LocalStorage client where an origin that previously
329 * was not using LocalStorage can start issuing writes which it buffers until
330 * eventually flushing them. We defer creating the origin directory for as
331 * long as possible in that case, so the directory won't exist. Logic that
332 * would otherwise only consult the filesystem also needs to use this method.
334 template <typename P>
335 void CollectPendingOriginsForListing(P aPredicate);
337 bool IsStorageInitialized() const {
338 AssertIsOnIOThread();
339 return static_cast<bool>(mStorageConnection);
342 void AssertStorageIsInitialized() const
343 #ifdef DEBUG
345 #else
348 #endif
350 nsresult EnsureStorageIsInitialized();
352 // Returns a pair of an nsIFile object referring to the directory, and a bool
353 // indicating whether the directory was newly created.
354 Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
355 EnsurePersistentOriginIsInitialized(const QuotaInfo& aQuotaInfo);
357 // Returns a pair of an nsIFile object referring to the directory, and a bool
358 // indicating whether the directory was newly created.
359 Result<std::pair<nsCOMPtr<nsIFile>, bool>, nsresult>
360 EnsureTemporaryOriginIsInitialized(PersistenceType aPersistenceType,
361 const QuotaInfo& aQuotaInfo);
363 nsresult EnsureTemporaryStorageIsInitialized();
365 void ShutdownStorage();
367 // Returns a bool indicating whether the directory was newly created.
368 Result<bool, nsresult> EnsureOriginDirectory(nsIFile& aDirectory);
370 nsresult AboutToClearOrigins(
371 const Nullable<PersistenceType>& aPersistenceType,
372 const OriginScope& aOriginScope,
373 const Nullable<Client::Type>& aClientType);
375 void OriginClearCompleted(PersistenceType aPersistenceType,
376 const nsACString& aOrigin,
377 const Nullable<Client::Type>& aClientType);
379 void StartIdleMaintenance() {
380 AssertIsOnOwningThread();
382 for (const auto& client : *mClients) {
383 client->StartIdleMaintenance();
387 void StopIdleMaintenance() {
388 AssertIsOnOwningThread();
390 for (const auto& client : *mClients) {
391 client->StopIdleMaintenance();
395 void AssertCurrentThreadOwnsQuotaMutex() {
396 mQuotaMutex.AssertCurrentThreadOwns();
399 nsIThread* IOThread() { return mIOThread->get(); }
401 Client* GetClient(Client::Type aClientType);
403 const AutoTArray<Client::Type, Client::TYPE_MAX>& AllClientTypes();
405 const nsString& GetBasePath() const { return mBasePath; }
407 const nsString& GetStorageName() const { return mStorageName; }
409 const nsString& GetStoragePath() const { return *mStoragePath; }
411 const nsString& GetStoragePath(PersistenceType aPersistenceType) const {
412 if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
413 return *mPermanentStoragePath;
416 if (aPersistenceType == PERSISTENCE_TYPE_TEMPORARY) {
417 return *mTemporaryStoragePath;
420 MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_DEFAULT);
422 return *mDefaultStoragePath;
425 uint64_t GetGroupLimit() const;
427 uint64_t GetGroupUsage(const nsACString& aGroup);
429 uint64_t GetOriginUsage(const GroupAndOrigin& aGroupAndOrigin);
431 void NotifyStoragePressure(uint64_t aUsage);
433 // Record a quota client shutdown step, if shutting down.
434 void MaybeRecordShutdownStep(Client::Type aClientType,
435 const nsACString& aStepDescription);
437 // Record a quota manager shutdown step, if shutting down.
438 void MaybeRecordQuotaManagerShutdownStep(const nsACString& aStepDescription);
440 static void GetStorageId(PersistenceType aPersistenceType,
441 const nsACString& aOrigin, Client::Type aClientType,
442 nsACString& aDatabaseId);
444 static bool IsPrincipalInfoValid(const PrincipalInfo& aPrincipalInfo);
446 static QuotaInfo GetInfoFromValidatedPrincipalInfo(
447 const PrincipalInfo& aPrincipalInfo);
449 static nsAutoCString GetOriginFromValidatedPrincipalInfo(
450 const PrincipalInfo& aPrincipalInfo);
452 static Result<QuotaInfo, nsresult> GetInfoFromPrincipal(
453 nsIPrincipal* aPrincipal);
455 static Result<nsAutoCString, nsresult> GetOriginFromPrincipal(
456 nsIPrincipal* aPrincipal);
458 static Result<nsAutoCString, nsresult> GetOriginFromWindow(
459 nsPIDOMWindowOuter* aWindow);
461 static nsLiteralCString GetOriginForChrome();
463 static QuotaInfo GetInfoForChrome();
465 static bool IsOriginInternal(const nsACString& aOrigin);
467 static bool AreOriginsEqualOnDisk(const nsACString& aOrigin1,
468 const nsACString& aOrigin2);
470 static Result<PrincipalInfo, nsresult> ParseOrigin(const nsACString& aOrigin);
472 static void InvalidateQuotaCache();
474 private:
475 QuotaManager(const nsAString& aBasePath, const nsAString& aStorageName);
477 virtual ~QuotaManager();
479 nsresult Init();
481 void Shutdown();
483 already_AddRefed<DirectoryLockImpl> CreateDirectoryLock(
484 const Nullable<PersistenceType>& aPersistenceType,
485 const nsACString& aGroup, const OriginScope& aOriginScope,
486 const Nullable<Client::Type>& aClientType, bool aExclusive,
487 bool aInternal, RefPtr<OpenDirectoryListener> aOpenListener,
488 bool& aBlockedOut);
490 already_AddRefed<DirectoryLockImpl> CreateDirectoryLockForEviction(
491 PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin);
493 void RegisterDirectoryLock(DirectoryLockImpl& aLock);
495 void UnregisterDirectoryLock(DirectoryLockImpl& aLock);
497 void RemovePendingDirectoryLock(DirectoryLockImpl& aLock);
499 uint64_t LockedCollectOriginsForEviction(
500 uint64_t aMinSizeToBeFreed, nsTArray<RefPtr<DirectoryLockImpl>>& aLocks);
502 void LockedRemoveQuotaForOrigin(PersistenceType aPersistenceType,
503 const GroupAndOrigin& aGroupAndOrigin);
505 already_AddRefed<GroupInfo> LockedGetOrCreateGroupInfo(
506 PersistenceType aPersistenceType, const nsACString& aGroup);
508 already_AddRefed<OriginInfo> LockedGetOriginInfo(
509 PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin);
511 nsresult UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
512 nsIFile* aIndexedDBDir);
514 nsresult UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
515 nsIFile* aPersistentStorageDir);
517 template <typename Helper>
518 nsresult UpgradeStorage(const int32_t aOldVersion, const int32_t aNewVersion,
519 mozIStorageConnection* aConnection);
521 nsresult UpgradeStorageFrom0_0To1_0(mozIStorageConnection* aConnection);
523 nsresult UpgradeStorageFrom1_0To2_0(mozIStorageConnection* aConnection);
525 nsresult UpgradeStorageFrom2_0To2_1(mozIStorageConnection* aConnection);
527 nsresult UpgradeStorageFrom2_1To2_2(mozIStorageConnection* aConnection);
529 nsresult UpgradeStorageFrom2_2To2_3(mozIStorageConnection* aConnection);
531 nsresult MaybeRemoveLocalStorageData();
533 nsresult MaybeRemoveLocalStorageDirectories();
535 Result<nsCOMPtr<mozIStorageConnection>, nsresult>
536 CreateLocalStorageArchiveConnectionFromWebAppsStore();
538 // The second object in the pair is used to signal if the localStorage
539 // archive database was newly created or recreated.
540 Result<std::pair<nsCOMPtr<mozIStorageConnection>, bool>, nsresult>
541 CreateLocalStorageArchiveConnection();
543 nsresult RecreateLocalStorageArchive(
544 nsCOMPtr<mozIStorageConnection>& aConnection);
546 nsresult DowngradeLocalStorageArchive(
547 nsCOMPtr<mozIStorageConnection>& aConnection);
549 nsresult UpgradeLocalStorageArchiveFromLessThan4To4(
550 nsCOMPtr<mozIStorageConnection>& aConnection);
553 nsresult UpgradeLocalStorageArchiveFrom4To5();
556 nsresult InitializeRepository(PersistenceType aPersistenceType);
558 nsresult InitializeOrigin(PersistenceType aPersistenceType,
559 const GroupAndOrigin& aGroupAndOrigin,
560 int64_t aAccessTime, bool aPersisted,
561 nsIFile* aDirectory);
563 void CheckTemporaryStorageLimits();
565 void DeleteFilesForOrigin(PersistenceType aPersistenceType,
566 const nsACString& aOrigin);
568 void FinalizeOriginEviction(nsTArray<RefPtr<DirectoryLockImpl>>&& aLocks);
570 void ReleaseIOThreadObjects() {
571 AssertIsOnIOThread();
573 for (Client::Type type : AllClientTypes()) {
574 (*mClients)[type]->ReleaseIOThreadObjects();
578 DirectoryLockTable& GetDirectoryLockTable(PersistenceType aPersistenceType);
580 bool IsSanitizedOriginValid(const nsACString& aSanitizedOrigin);
582 int64_t GenerateDirectoryLockId();
584 void MaybeRecordShutdownStep(Maybe<Client::Type> aClientType,
585 const nsACString& aStepDescription);
587 // Thread on which IO is performed.
588 LazyInitializedOnceNotNull<const nsCOMPtr<nsIThread>> mIOThread;
590 nsCOMPtr<mozIStorageConnection> mStorageConnection;
592 // A timer that gets activated at shutdown to ensure we close all storages.
593 LazyInitializedOnceNotNull<const nsCOMPtr<nsITimer>> mShutdownTimer;
595 EnumeratedArray<Client::Type, Client::TYPE_MAX, nsCString> mShutdownSteps;
596 LazyInitializedOnce<const TimeStamp> mShutdownStartedAt;
597 Atomic<bool> mShutdownStarted;
599 // Accesses to mQuotaManagerShutdownSteps must be protected by mQuotaMutex.
600 nsCString mQuotaManagerShutdownSteps;
602 mozilla::Mutex mQuotaMutex;
604 nsClassHashtable<nsCStringHashKey, GroupInfoPair> mGroupInfoPairs;
606 // Maintains a list of directory locks that are queued.
607 nsTArray<RefPtr<DirectoryLockImpl>> mPendingDirectoryLocks;
609 // Maintains a list of directory locks that are acquired or queued. It can be
610 // accessed on the owning (PBackground) thread only.
611 nsTArray<NotNull<DirectoryLockImpl*>> mDirectoryLocks;
613 // Only modifed on the owning thread, but read on multiple threads. Therefore
614 // all modifications (including those on the owning thread) and all reads off
615 // the owning thread must be protected by mQuotaMutex. In other words, only
616 // reads on the owning thread don't have to be protected by mQuotaMutex.
617 nsDataHashtable<nsUint64HashKey, NotNull<DirectoryLockImpl*>>
618 mDirectoryLockIdTable;
620 // Directory lock tables that are used to update origin access time.
621 DirectoryLockTable mTemporaryDirectoryLockTable;
622 DirectoryLockTable mDefaultDirectoryLockTable;
624 // A list of all successfully initialized persistent origins. This list isn't
625 // protected by any mutex but it is only ever touched on the IO thread.
626 nsTArray<nsCString> mInitializedOrigins;
628 // A hash table that is used to cache origin parser results for given
629 // sanitized origin strings. This hash table isn't protected by any mutex but
630 // it is only ever touched on the IO thread.
631 nsDataHashtable<nsCStringHashKey, bool> mValidOrigins;
633 struct OriginInitializationInfo {
634 bool mPersistentOriginAttempted : 1;
635 bool mTemporaryOriginAttempted : 1;
638 // A hash table that is currently used to track origin initialization
639 // attempts. This hash table isn't protected by any mutex but it is only ever
640 // touched on the IO thread.
641 nsDataHashtable<nsCStringHashKey, OriginInitializationInfo>
642 mOriginInitializationInfos;
644 // This array is populated at initialization time and then never modified, so
645 // it can be iterated on any thread.
646 LazyInitializedOnce<const AutoTArray<RefPtr<Client>, Client::TYPE_MAX>>
647 mClients;
649 using ClientTypesArray = AutoTArray<Client::Type, Client::TYPE_MAX>;
650 LazyInitializedOnce<const ClientTypesArray> mAllClientTypes;
651 LazyInitializedOnce<const ClientTypesArray> mAllClientTypesExceptLS;
653 InitializationInfo mInitializationInfo;
655 const nsString mBasePath;
656 const nsString mStorageName;
657 LazyInitializedOnce<const nsString> mIndexedDBPath;
658 LazyInitializedOnce<const nsString> mStoragePath;
659 LazyInitializedOnce<const nsString> mPermanentStoragePath;
660 LazyInitializedOnce<const nsString> mTemporaryStoragePath;
661 LazyInitializedOnce<const nsString> mDefaultStoragePath;
663 uint64_t mTemporaryStorageLimit;
664 uint64_t mTemporaryStorageUsage;
665 int64_t mNextDirectoryLockId;
666 bool mTemporaryStorageInitialized;
667 bool mCacheUsable;
670 } // namespace mozilla::dom::quota
672 #endif /* mozilla_dom_quota_quotamanager_h__ */