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__
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"
27 #include "nsClassHashtable.h"
28 #include "nsDataHashtable.h"
30 #include "nsHashKeys.h"
31 #include "nsISupports.h"
32 #include "nsStringFwd.h"
34 #include "nsTStringRepr.h"
38 #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
40 class mozIStorageConnection
;
47 class nsPIDOMWindowOuter
;
51 class OriginAttributes
;
59 } // namespace mozilla
61 namespace mozilla::dom::quota
{
63 class ClientUsageArray
;
64 class DirectoryLockImpl
;
71 class NS_NO_VTABLE RefCountedObject
{
73 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
76 class DirectoryLock
: public RefCountedObject
{
77 friend class DirectoryLockImpl
;
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;
99 DirectoryLock() = default;
101 ~DirectoryLock() = default;
104 class NS_NO_VTABLE OpenDirectoryListener
: public RefCountedObject
{
106 virtual void DirectoryLockAcquired(DirectoryLock
* aLock
) = 0;
108 virtual void DirectoryLockFailed() = 0;
111 virtual ~OpenDirectoryListener() = default;
114 struct OriginParams
{
115 OriginParams(PersistenceType aPersistenceType
, const nsACString
& aOrigin
)
116 : mOrigin(aOrigin
), mPersistenceType(aPersistenceType
) {}
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
*>>>
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
188 void InitQuotaForOrigin(PersistenceType aPersistenceType
,
189 const GroupAndOrigin
& aGroupAndOrigin
,
190 const ClientUsageArray
& aClientUsages
,
191 uint64_t aUsageBytes
, int64_t aAccessTime
,
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
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
);
235 void RemoveQuotaForOrigin(PersistenceType aPersistenceType
,
236 const GroupAndOrigin
& aGroupAndOrigin
) {
237 MutexAutoLock
lock(mQuotaMutex
);
238 LockedRemoveQuotaForOrigin(aPersistenceType
, aGroupAndOrigin
);
241 nsresult
LoadQuota();
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
{
276 struct GetDirectoryResultWithQuotaInfo
: GetDirectoryResult
{
277 QuotaInfo mQuotaInfo
;
280 Result
<GetDirectoryResultWithQuotaInfo
, nsresult
>
281 GetDirectoryMetadataWithQuotaInfo2(nsIFile
* aDirectory
);
283 Result
<GetDirectoryResultWithQuotaInfo
, nsresult
>
284 GetDirectoryMetadataWithQuotaInfo2WithRestore(nsIFile
* aDirectory
,
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
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
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();
475 QuotaManager(const nsAString
& aBasePath
, const nsAString
& aStorageName
);
477 virtual ~QuotaManager();
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
,
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
>>
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
;
670 } // namespace mozilla::dom::quota
672 #endif /* mozilla_dom_quota_quotamanager_h__ */