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/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/DirectoryLockCategory.h"
26 #include "mozilla/dom/quota/ForwardDecls.h"
27 #include "mozilla/dom/quota/InitializationTypes.h"
28 #include "mozilla/dom/quota/PersistenceType.h"
29 #include "mozilla/dom/quota/QuotaCommon.h"
31 #include "nsClassHashtable.h"
32 #include "nsTHashMap.h"
34 #include "nsHashKeys.h"
35 #include "nsISupports.h"
36 #include "nsStringFwd.h"
38 #include "nsTStringRepr.h"
42 #define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
44 class mozIStorageConnection
;
51 class nsPIDOMWindowOuter
;
55 class OriginAttributes
;
56 class OriginAttributesPattern
;
64 } // namespace mozilla
66 namespace mozilla::dom::quota
{
68 class CanonicalQuotaObject
;
69 class ClientUsageArray
;
70 class ClientDirectoryLock
;
71 class DirectoryLockImpl
;
74 class NormalOriginOperationBase
;
75 class OriginDirectoryLock
;
79 class UniversalDirectoryLock
;
81 class QuotaManager final
: public BackgroundThreadObject
{
82 friend class CanonicalQuotaObject
;
83 friend class ClearStorageOp
;
84 friend class DirectoryLockImpl
;
85 friend class GroupInfo
;
87 friend class OriginInfo
;
88 friend class ShutdownStorageOp
;
90 using PrincipalInfo
= mozilla::ipc::PrincipalInfo
;
91 using DirectoryLockTable
=
92 nsClassHashtable
<nsCStringHashKey
, nsTArray
<NotNull
<DirectoryLockImpl
*>>>;
97 QuotaManager(const nsAString
& aBasePath
, const nsAString
& aStorageName
);
99 NS_INLINE_DECL_REFCOUNTING(QuotaManager
)
101 static nsresult
Initialize();
103 static bool IsRunningXPCShellTests() {
104 static bool kRunningXPCShellTests
=
105 !!PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR");
106 return kRunningXPCShellTests
;
109 static bool IsRunningGTests() {
110 static bool kRunningGTests
= !!PR_GetEnv("MOZ_RUN_GTEST");
111 return kRunningGTests
;
114 static const char kReplaceChars
[];
115 static const char16_t kReplaceChars16
[];
117 static Result
<MovingNotNull
<RefPtr
<QuotaManager
>>, nsresult
> GetOrCreate();
119 static Result
<Ok
, nsresult
> EnsureCreated();
121 // Returns a non-owning reference.
122 static QuotaManager
* Get();
124 // Use only in gtests!
125 static nsIObserver
* GetObserver();
127 // Returns true if we've begun the shutdown process.
128 static bool IsShuttingDown();
130 static void ShutdownInstance();
132 // Use only in gtests!
135 static bool IsOSMetadata(const nsAString
& aFileName
);
137 static bool IsDotFile(const nsAString
& aFileName
);
139 void RegisterNormalOriginOp(NormalOriginOperationBase
& aNormalOriginOp
);
141 void UnregisterNormalOriginOp(NormalOriginOperationBase
& aNormalOriginOp
);
143 bool IsOriginInitialized(const nsACString
& aOrigin
) const {
144 AssertIsOnIOThread();
146 return mInitializedOrigins
.Contains(aOrigin
);
149 bool IsTemporaryStorageInitializedInternal() const {
150 AssertIsOnIOThread();
152 return mTemporaryStorageInitializedInternal
;
156 * For initialization of an origin where the directory already exists. This is
157 * used by EnsureTemporaryStorageIsInitializedInternal/InitializeRepository
158 * once it has tallied origin usage by calling each of the QuotaClient
159 * InitOrigin methods.
161 void InitQuotaForOrigin(const FullOriginMetadata
& aFullOriginMetadata
,
162 const ClientUsageArray
& aClientUsages
,
163 uint64_t aUsageBytes
);
166 * For use in special-cases like LSNG where we need to be able to know that
167 * there is no data stored for an origin. LSNG knows that there is 0 usage for
168 * its storage of an origin and wants to make sure there is a QuotaObject
169 * tracking this. This method will create a non-persisted, 0-usage,
170 * mDirectoryExists=false OriginInfo if there isn't already an OriginInfo. If
171 * an OriginInfo already exists, it will be left as-is, because that implies a
172 * different client has usages for the origin (and there's no need to add
173 * LSNG's 0 usage to the QuotaObject).
175 void EnsureQuotaForOrigin(const OriginMetadata
& aOriginMetadata
);
178 * For use when creating an origin directory. It's possible that origin usage
179 * is already being tracked due to a call to EnsureQuotaForOrigin, and in that
180 * case we need to update the existing OriginInfo rather than create a new
183 * @return last access time of the origin.
185 int64_t NoteOriginDirectoryCreated(const OriginMetadata
& aOriginMetadata
,
188 // XXX clients can use QuotaObject instead of calling this method directly.
189 void DecreaseUsageForClient(const ClientMetadata
& aClientMetadata
,
192 void ResetUsageForClient(const ClientMetadata
& aClientMetadata
);
194 UsageInfo
GetUsageForClient(PersistenceType aPersistenceType
,
195 const OriginMetadata
& aOriginMetadata
,
196 Client::Type aClientType
);
198 void UpdateOriginAccessTime(PersistenceType aPersistenceType
,
199 const OriginMetadata
& aOriginMetadata
);
203 void RemoveQuotaForRepository(PersistenceType aPersistenceType
) {
204 MutexAutoLock
lock(mQuotaMutex
);
205 LockedRemoveQuotaForRepository(aPersistenceType
);
208 void RemoveQuotaForOrigin(PersistenceType aPersistenceType
,
209 const OriginMetadata
& aOriginMetadata
) {
210 MutexAutoLock
lock(mQuotaMutex
);
211 LockedRemoveQuotaForOrigin(aOriginMetadata
);
214 nsresult
LoadQuota();
218 already_AddRefed
<QuotaObject
> GetQuotaObject(
219 PersistenceType aPersistenceType
, const OriginMetadata
& aOriginMetadata
,
220 Client::Type aClientType
, nsIFile
* aFile
, int64_t aFileSize
= -1,
221 int64_t* aFileSizeOut
= nullptr);
223 already_AddRefed
<QuotaObject
> GetQuotaObject(
224 PersistenceType aPersistenceType
, const OriginMetadata
& aOriginMetadata
,
225 Client::Type aClientType
, const nsAString
& aPath
, int64_t aFileSize
= -1,
226 int64_t* aFileSizeOut
= nullptr);
228 already_AddRefed
<QuotaObject
> GetQuotaObject(const int64_t aDirectoryLockId
,
229 const nsAString
& aPath
);
231 Nullable
<bool> OriginPersisted(const OriginMetadata
& aOriginMetadata
);
233 void PersistOrigin(const OriginMetadata
& aOriginMetadata
);
235 using DirectoryLockIdTableArray
=
236 AutoTArray
<Client::DirectoryLockIdTable
, Client::TYPE_MAX
>;
237 void AbortOperationsForLocks(const DirectoryLockIdTableArray
& aLockIds
);
239 // Called when a process is being shot down. Aborts any running operations
240 // for the given process.
241 void AbortOperationsForProcess(ContentParentId aContentParentId
);
243 Result
<nsCOMPtr
<nsIFile
>, nsresult
> GetOriginDirectory(
244 const OriginMetadata
& aOriginMetadata
) const;
246 Result
<bool, nsresult
> DoesOriginDirectoryExist(
247 const OriginMetadata
& aOriginMetadata
) const;
249 static nsresult
CreateDirectoryMetadata(
250 nsIFile
& aDirectory
, int64_t aTimestamp
,
251 const OriginMetadata
& aOriginMetadata
);
253 static nsresult
CreateDirectoryMetadata2(
254 nsIFile
& aDirectory
, int64_t aTimestamp
, bool aPersisted
,
255 const OriginMetadata
& aOriginMetadata
);
257 nsresult
RestoreDirectoryMetadata2(nsIFile
* aDirectory
);
259 // XXX Remove aPersistenceType argument once the persistence type is stored
260 // in the metadata file.
261 Result
<FullOriginMetadata
, nsresult
> LoadFullOriginMetadata(
262 nsIFile
* aDirectory
, PersistenceType aPersistenceType
);
264 Result
<FullOriginMetadata
, nsresult
> LoadFullOriginMetadataWithRestore(
265 nsIFile
* aDirectory
);
267 Result
<OriginMetadata
, nsresult
> GetOriginMetadata(nsIFile
* aDirectory
);
269 Result
<Ok
, nsresult
> RemoveOriginDirectory(nsIFile
& aDirectory
);
271 Result
<bool, nsresult
> DoesClientDirectoryExist(
272 const ClientMetadata
& aClientMetadata
) const;
274 RefPtr
<UniversalDirectoryLockPromise
> OpenStorageDirectory(
275 const Nullable
<PersistenceType
>& aPersistenceType
,
276 const OriginScope
& aOriginScope
,
277 const Nullable
<Client::Type
>& aClientType
, bool aExclusive
,
278 DirectoryLockCategory aCategory
= DirectoryLockCategory::None
,
279 Maybe
<RefPtr
<UniversalDirectoryLock
>&> aPendingDirectoryLockOut
=
282 // This is the main entry point into the QuotaManager API.
283 // Any storage API implementation (quota client) that participates in
284 // centralized quota and storage handling should call this method to get
285 // a directory lock which will protect client's files from being deleted
286 // while they are still in use.
287 // After a lock is acquired, client is notified by resolving the returned
288 // promise. If the lock couldn't be acquired, client is notified by rejecting
289 // the returned promise.
290 // A lock is a reference counted object and at the time the returned promise
291 // is resolved, there are no longer other strong references except the one
292 // held by the resolve value itself. So it's up to client to add a new
293 // reference in order to keep the lock alive.
294 // Unlocking is simply done by dropping all references to the lock object.
295 // In other words, protection which the lock represents dies with the lock
296 // object itself (Note that it's now possible to release directory locks
297 // sooner by calling newly added Drop method).
298 RefPtr
<ClientDirectoryLockPromise
> OpenClientDirectory(
299 const ClientMetadata
& aClientMetadata
,
300 Maybe
<RefPtr
<ClientDirectoryLock
>&> aPendingDirectoryLockOut
= Nothing());
302 RefPtr
<ClientDirectoryLock
> CreateDirectoryLock(
303 const ClientMetadata
& aClientMetadata
, bool aExclusive
);
305 // XXX RemoveMe once bug 1170279 gets fixed.
306 RefPtr
<UniversalDirectoryLock
> CreateDirectoryLockInternal(
307 const Nullable
<PersistenceType
>& aPersistenceType
,
308 const OriginScope
& aOriginScope
,
309 const Nullable
<Client::Type
>& aClientType
, bool aExclusive
,
310 DirectoryLockCategory aCategory
= DirectoryLockCategory::None
);
312 // Collect inactive and the least recently used origins.
313 uint64_t CollectOriginsForEviction(
314 uint64_t aMinSizeToBeFreed
,
315 nsTArray
<RefPtr
<OriginDirectoryLock
>>& aLocks
);
318 * Helper method to invoke the provided predicate on all "pending" OriginInfo
319 * instances. These are origins for which the origin directory has not yet
320 * been created but for which quota is already being tracked. This happens,
321 * for example, for the LocalStorage client where an origin that previously
322 * was not using LocalStorage can start issuing writes which it buffers until
323 * eventually flushing them. We defer creating the origin directory for as
324 * long as possible in that case, so the directory won't exist. Logic that
325 * would otherwise only consult the filesystem also needs to use this method.
327 template <typename P
>
328 void CollectPendingOriginsForListing(P aPredicate
);
330 RefPtr
<BoolPromise
> InitializeStorage();
332 RefPtr
<BoolPromise
> InitializeStorage(
333 RefPtr
<UniversalDirectoryLock
> aDirectoryLock
);
335 RefPtr
<BoolPromise
> StorageInitialized();
337 bool IsStorageInitialized() const {
338 AssertIsOnOwningThread();
340 return mStorageInitialized
;
343 bool IsStorageInitializedInternal() const {
344 AssertIsOnIOThread();
345 return static_cast<bool>(mStorageConnection
);
348 void AssertStorageIsInitializedInternal() const
356 RefPtr
<BoolPromise
> TemporaryStorageInitialized();
359 nsresult
EnsureStorageIsInitializedInternal();
362 // Returns a pair of an nsIFile object referring to the directory, and a bool
363 // indicating whether the directory was newly created.
364 Result
<std::pair
<nsCOMPtr
<nsIFile
>, bool>, nsresult
>
365 EnsurePersistentOriginIsInitialized(const OriginMetadata
& aOriginMetadata
);
367 bool IsTemporaryOriginInitialized(
368 const OriginMetadata
& aOriginMetadata
) const;
370 // Returns a pair of an nsIFile object referring to the directory, and a bool
371 // indicating whether the directory was newly created.
372 Result
<std::pair
<nsCOMPtr
<nsIFile
>, bool>, nsresult
>
373 EnsureTemporaryOriginIsInitialized(PersistenceType aPersistenceType
,
374 const OriginMetadata
& aOriginMetadata
);
376 RefPtr
<BoolPromise
> InitializePersistentClient(
377 const PrincipalInfo
& aPrincipalInfo
, Client::Type aClientType
);
379 // Returns a pair of an nsIFile object referring to the directory, and a bool
380 // indicating whether the directory was newly created.
381 Result
<std::pair
<nsCOMPtr
<nsIFile
>, bool>, nsresult
>
382 EnsurePersistentClientIsInitialized(const ClientMetadata
& aClientMetadata
);
384 RefPtr
<BoolPromise
> InitializeTemporaryClient(
385 PersistenceType aPersistenceType
, const PrincipalInfo
& aPrincipalInfo
,
386 Client::Type aClientType
);
388 // Returns a pair of an nsIFile object referring to the directory, and a bool
389 // indicating whether the directory was newly created.
390 Result
<std::pair
<nsCOMPtr
<nsIFile
>, bool>, nsresult
>
391 EnsureTemporaryClientIsInitialized(const ClientMetadata
& aClientMetadata
);
393 RefPtr
<BoolPromise
> InitializeTemporaryStorage();
395 RefPtr
<BoolPromise
> InitializeTemporaryStorage(
396 RefPtr
<UniversalDirectoryLock
> aDirectoryLock
);
398 bool IsTemporaryStorageInitialized() const {
399 AssertIsOnOwningThread();
401 return mTemporaryStorageInitialized
;
404 nsresult
EnsureTemporaryStorageIsInitializedInternal();
406 RefPtr
<BoolPromise
> ClearStoragesForOrigin(
407 const Maybe
<PersistenceType
>& aPersistenceType
,
408 const PrincipalInfo
& aPrincipalInfo
,
409 const Maybe
<Client::Type
>& aClientType
);
411 RefPtr
<BoolPromise
> ClearStoragesForOriginPrefix(
412 const Maybe
<PersistenceType
>& aPersistenceType
,
413 const PrincipalInfo
& aPrincipalInfo
);
415 RefPtr
<BoolPromise
> ClearStoragesForOriginAttributesPattern(
416 const OriginAttributesPattern
& aPattern
);
418 RefPtr
<BoolPromise
> ClearPrivateRepository();
420 RefPtr
<BoolPromise
> ClearStorage();
422 RefPtr
<BoolPromise
> ShutdownStorage();
424 void ShutdownStorageInternal();
426 // Returns a bool indicating whether the directory was newly created.
427 Result
<bool, nsresult
> EnsureOriginDirectory(nsIFile
& aDirectory
);
429 nsresult
AboutToClearOrigins(
430 const Nullable
<PersistenceType
>& aPersistenceType
,
431 const OriginScope
& aOriginScope
,
432 const Nullable
<Client::Type
>& aClientType
);
434 void OriginClearCompleted(PersistenceType aPersistenceType
,
435 const nsACString
& aOrigin
,
436 const Nullable
<Client::Type
>& aClientType
);
438 void RepositoryClearCompleted(PersistenceType aPersistenceType
);
440 void StartIdleMaintenance() {
441 AssertIsOnOwningThread();
443 for (const auto& client
: *mClients
) {
444 client
->StartIdleMaintenance();
448 void StopIdleMaintenance() {
449 AssertIsOnOwningThread();
451 for (const auto& client
: *mClients
) {
452 client
->StopIdleMaintenance();
456 void AssertCurrentThreadOwnsQuotaMutex() {
457 mQuotaMutex
.AssertCurrentThreadOwns();
460 nsIThread
* IOThread() { return mIOThread
->get(); }
462 Client
* GetClient(Client::Type aClientType
);
464 const AutoTArray
<Client::Type
, Client::TYPE_MAX
>& AllClientTypes();
466 const nsString
& GetBasePath() const { return mBasePath
; }
468 const nsString
& GetStorageName() const { return mStorageName
; }
470 const nsString
& GetStoragePath() const { return *mStoragePath
; }
472 const nsString
& GetStoragePath(PersistenceType aPersistenceType
) const {
473 if (aPersistenceType
== PERSISTENCE_TYPE_PERSISTENT
) {
474 return *mPermanentStoragePath
;
477 if (aPersistenceType
== PERSISTENCE_TYPE_TEMPORARY
) {
478 return *mTemporaryStoragePath
;
481 if (aPersistenceType
== PERSISTENCE_TYPE_DEFAULT
) {
482 return *mDefaultStoragePath
;
485 MOZ_ASSERT(aPersistenceType
== PERSISTENCE_TYPE_PRIVATE
);
487 return *mPrivateStoragePath
;
490 uint64_t GetGroupLimit() const;
492 std::pair
<uint64_t, uint64_t> GetUsageAndLimitForEstimate(
493 const OriginMetadata
& aOriginMetadata
);
495 uint64_t GetOriginUsage(const PrincipalMetadata
& aPrincipalMetadata
);
497 Maybe
<FullOriginMetadata
> GetFullOriginMetadata(
498 const OriginMetadata
& aOriginMetadata
);
500 void NotifyStoragePressure(uint64_t aUsage
);
502 // Record a quota client shutdown step, if shutting down.
503 // Assumes that the QuotaManager singleton is alive.
504 static void MaybeRecordQuotaClientShutdownStep(
505 const Client::Type aClientType
, const nsACString
& aStepDescription
);
507 // Record a quota client shutdown step, if shutting down.
508 // Checks if the QuotaManager singleton is alive.
509 static void SafeMaybeRecordQuotaClientShutdownStep(
510 Client::Type aClientType
, const nsACString
& aStepDescription
);
512 // Record a quota manager shutdown step, use only if shutdown is active.
513 void RecordQuotaManagerShutdownStep(const nsACString
& aStepDescription
);
515 // Record a quota manager shutdown step, if shutting down.
516 void MaybeRecordQuotaManagerShutdownStep(const nsACString
& aStepDescription
);
518 template <typename F
>
519 void MaybeRecordQuotaManagerShutdownStepWith(F
&& aFunc
);
521 static void GetStorageId(PersistenceType aPersistenceType
,
522 const nsACString
& aOrigin
, Client::Type aClientType
,
523 nsACString
& aDatabaseId
);
525 static bool IsPrincipalInfoValid(const PrincipalInfo
& aPrincipalInfo
);
527 Result
<PrincipalMetadata
, nsresult
> GetInfoFromValidatedPrincipalInfo(
528 const PrincipalInfo
& aPrincipalInfo
);
530 static nsAutoCString
GetOriginFromValidatedPrincipalInfo(
531 const PrincipalInfo
& aPrincipalInfo
);
533 static Result
<PrincipalMetadata
, nsresult
> GetInfoFromPrincipal(
534 nsIPrincipal
* aPrincipal
);
536 static Result
<PrincipalMetadata
, nsresult
> GetInfoFromWindow(
537 nsPIDOMWindowOuter
* aWindow
);
539 static Result
<nsAutoCString
, nsresult
> GetOriginFromPrincipal(
540 nsIPrincipal
* aPrincipal
);
542 static Result
<nsAutoCString
, nsresult
> GetOriginFromWindow(
543 nsPIDOMWindowOuter
* aWindow
);
545 static nsLiteralCString
GetOriginForChrome();
547 static PrincipalMetadata
GetInfoForChrome();
549 static bool IsOriginInternal(const nsACString
& aOrigin
);
551 static bool AreOriginsEqualOnDisk(const nsACString
& aOrigin1
,
552 const nsACString
& aOrigin2
);
554 // XXX This method currently expects the original origin string (not yet
556 static Result
<PrincipalInfo
, nsresult
> ParseOrigin(const nsACString
& aOrigin
);
558 static void InvalidateQuotaCache();
561 virtual ~QuotaManager();
567 void RegisterDirectoryLock(DirectoryLockImpl
& aLock
);
569 void UnregisterDirectoryLock(DirectoryLockImpl
& aLock
);
571 void AddPendingDirectoryLock(DirectoryLockImpl
& aLock
);
573 void RemovePendingDirectoryLock(DirectoryLockImpl
& aLock
);
575 uint64_t LockedCollectOriginsForEviction(
576 uint64_t aMinSizeToBeFreed
,
577 nsTArray
<RefPtr
<OriginDirectoryLock
>>& aLocks
);
579 void LockedRemoveQuotaForRepository(PersistenceType aPersistenceType
);
581 void LockedRemoveQuotaForOrigin(const OriginMetadata
& aOriginMetadata
);
583 already_AddRefed
<GroupInfo
> LockedGetOrCreateGroupInfo(
584 PersistenceType aPersistenceType
, const nsACString
& aSuffix
,
585 const nsACString
& aGroup
);
587 already_AddRefed
<OriginInfo
> LockedGetOriginInfo(
588 PersistenceType aPersistenceType
,
589 const OriginMetadata
& aOriginMetadata
) const;
591 nsresult
UpgradeFromIndexedDBDirectoryToPersistentStorageDirectory(
592 nsIFile
* aIndexedDBDir
);
594 nsresult
UpgradeFromPersistentStorageDirectoryToDefaultStorageDirectory(
595 nsIFile
* aPersistentStorageDir
);
597 nsresult
MaybeUpgradeToDefaultStorageDirectory(nsIFile
& aStorageFile
);
599 template <typename Helper
>
600 nsresult
UpgradeStorage(const int32_t aOldVersion
, const int32_t aNewVersion
,
601 mozIStorageConnection
* aConnection
);
603 nsresult
UpgradeStorageFrom0_0To1_0(mozIStorageConnection
* aConnection
);
605 nsresult
UpgradeStorageFrom1_0To2_0(mozIStorageConnection
* aConnection
);
607 nsresult
UpgradeStorageFrom2_0To2_1(mozIStorageConnection
* aConnection
);
609 nsresult
UpgradeStorageFrom2_1To2_2(mozIStorageConnection
* aConnection
);
611 nsresult
UpgradeStorageFrom2_2To2_3(mozIStorageConnection
* aConnection
);
613 nsresult
MaybeCreateOrUpgradeStorage(mozIStorageConnection
& aConnection
);
615 OkOrErr
MaybeRemoveLocalStorageArchiveTmpFile();
617 nsresult
MaybeRemoveLocalStorageDataAndArchive(nsIFile
& aLsArchiveFile
);
619 nsresult
MaybeRemoveLocalStorageDirectories();
621 Result
<Ok
, nsresult
> CopyLocalStorageArchiveFromWebAppsStore(
622 nsIFile
& aLsArchiveFile
) const;
624 Result
<nsCOMPtr
<mozIStorageConnection
>, nsresult
>
625 CreateLocalStorageArchiveConnection(nsIFile
& aLsArchiveFile
) const;
627 Result
<nsCOMPtr
<mozIStorageConnection
>, nsresult
>
628 RecopyLocalStorageArchiveFromWebAppsStore(nsIFile
& aLsArchiveFile
);
630 Result
<nsCOMPtr
<mozIStorageConnection
>, nsresult
>
631 DowngradeLocalStorageArchive(nsIFile
& aLsArchiveFile
);
633 Result
<nsCOMPtr
<mozIStorageConnection
>, nsresult
>
634 UpgradeLocalStorageArchiveFromLessThan4To4(nsIFile
& aLsArchiveFile
);
637 nsresult UpgradeLocalStorageArchiveFrom4To5();
640 Result
<Ok
, nsresult
> MaybeCreateOrUpgradeLocalStorageArchive(
641 nsIFile
& aLsArchiveFile
);
643 Result
<Ok
, nsresult
> CreateEmptyLocalStorageArchive(
644 nsIFile
& aLsArchiveFile
) const;
646 template <typename OriginFunc
>
647 nsresult
InitializeRepository(PersistenceType aPersistenceType
,
648 OriginFunc
&& aOriginFunc
);
650 nsresult
InitializeOrigin(PersistenceType aPersistenceType
,
651 const OriginMetadata
& aOriginMetadata
,
652 int64_t aAccessTime
, bool aPersisted
,
653 nsIFile
* aDirectory
);
655 using OriginInfosFlatTraversable
=
656 nsTArray
<NotNull
<RefPtr
<const OriginInfo
>>>;
658 using OriginInfosNestedTraversable
=
659 nsTArray
<nsTArray
<NotNull
<RefPtr
<const OriginInfo
>>>>;
661 OriginInfosNestedTraversable
GetOriginInfosExceedingGroupLimit() const;
663 OriginInfosNestedTraversable
GetOriginInfosExceedingGlobalLimit() const;
665 void ClearOrigins(const OriginInfosNestedTraversable
& aDoomedOriginInfos
);
667 void CleanupTemporaryStorage();
669 void DeleteOriginDirectory(const OriginMetadata
& aOriginMetadata
);
671 void FinalizeOriginEviction(nsTArray
<RefPtr
<OriginDirectoryLock
>>&& aLocks
);
673 Result
<Ok
, nsresult
> ArchiveOrigins(
674 const nsTArray
<FullOriginMetadata
>& aFullOriginMetadatas
);
676 void ReleaseIOThreadObjects() {
677 AssertIsOnIOThread();
679 for (Client::Type type
: AllClientTypes()) {
680 (*mClients
)[type
]->ReleaseIOThreadObjects();
684 DirectoryLockTable
& GetDirectoryLockTable(PersistenceType aPersistenceType
);
686 void ClearDirectoryLockTables();
688 bool IsSanitizedOriginValid(const nsACString
& aSanitizedOrigin
);
690 Result
<nsCString
, nsresult
> EnsureStorageOriginFromOrigin(
691 const nsACString
& aOrigin
);
693 Result
<nsCString
, nsresult
> GetOriginFromStorageOrigin(
694 const nsACString
& aStorageOrigin
);
696 int64_t GenerateDirectoryLockId();
698 bool ShutdownStarted() const;
700 void RecordShutdownStep(Maybe
<Client::Type
> aClientType
,
701 const nsACString
& aStepDescription
);
703 template <typename Func
>
704 auto ExecuteInitialization(Initialization aInitialization
, Func
&& aFunc
)
705 -> std::invoke_result_t
<Func
, const FirstInitializationAttempt
<
706 Initialization
, StringGenerator
>&>;
708 template <typename Func
>
709 auto ExecuteInitialization(Initialization aInitialization
,
710 const nsACString
& aContext
, Func
&& aFunc
)
711 -> std::invoke_result_t
<Func
, const FirstInitializationAttempt
<
712 Initialization
, StringGenerator
>&>;
714 template <typename Func
>
715 auto ExecuteOriginInitialization(const nsACString
& aOrigin
,
716 const OriginInitialization aInitialization
,
717 const nsACString
& aContext
, Func
&& aFunc
)
718 -> std::invoke_result_t
<Func
, const FirstInitializationAttempt
<
719 Initialization
, StringGenerator
>&>;
721 template <typename Iterator
>
722 static void MaybeInsertNonPersistedOriginInfos(
723 Iterator aDest
, const RefPtr
<GroupInfo
>& aTemporaryGroupInfo
,
724 const RefPtr
<GroupInfo
>& aDefaultGroupInfo
,
725 const RefPtr
<GroupInfo
>& aPrivateGroupInfo
);
727 template <typename Collect
, typename Pred
>
728 static OriginInfosFlatTraversable
CollectLRUOriginInfosUntil(
729 Collect
&& aCollect
, Pred
&& aPred
);
731 // Thread on which IO is performed.
732 LazyInitializedOnceNotNull
<const nsCOMPtr
<nsIThread
>> mIOThread
;
734 nsCOMPtr
<mozIStorageConnection
> mStorageConnection
;
736 EnumeratedArray
<Client::Type
, nsCString
, size_t(Client::TYPE_MAX
)>
738 LazyInitializedOnce
<const TimeStamp
> mShutdownStartedAt
;
740 // Accesses to mQuotaManagerShutdownSteps must be protected by mQuotaMutex.
741 nsCString mQuotaManagerShutdownSteps
;
743 mutable mozilla::Mutex mQuotaMutex MOZ_UNANNOTATED
;
745 nsClassHashtable
<nsCStringHashKey
, GroupInfoPair
> mGroupInfoPairs
;
747 // Maintains a list of directory locks that are queued.
748 nsTArray
<RefPtr
<DirectoryLockImpl
>> mPendingDirectoryLocks
;
750 // Maintains a list of directory locks that are acquired or queued. It can be
751 // accessed on the owning (PBackground) thread only.
752 nsTArray
<NotNull
<DirectoryLockImpl
*>> mDirectoryLocks
;
754 // Only modifed on the owning thread, but read on multiple threads. Therefore
755 // all modifications (including those on the owning thread) and all reads off
756 // the owning thread must be protected by mQuotaMutex. In other words, only
757 // reads on the owning thread don't have to be protected by mQuotaMutex.
758 nsTHashMap
<nsUint64HashKey
, NotNull
<DirectoryLockImpl
*>>
759 mDirectoryLockIdTable
;
761 // Directory lock tables that are used to update origin access time.
762 DirectoryLockTable mTemporaryDirectoryLockTable
;
763 DirectoryLockTable mDefaultDirectoryLockTable
;
764 DirectoryLockTable mPrivateDirectoryLockTable
;
766 // A list of all successfully initialized persistent origins. This list isn't
767 // protected by any mutex but it is only ever touched on the IO thread.
768 nsTArray
<nsCString
> mInitializedOrigins
;
770 // A hash table that is used to cache origin parser results for given
771 // sanitized origin strings. This hash table isn't protected by any mutex but
772 // it is only ever touched on the IO thread.
773 nsTHashMap
<nsCStringHashKey
, bool> mValidOrigins
;
775 // These maps are protected by mQuotaMutex.
776 nsTHashMap
<nsCStringHashKey
, nsCString
> mOriginToStorageOriginMap
;
777 nsTHashMap
<nsCStringHashKey
, nsCString
> mStorageOriginToOriginMap
;
779 // This array is populated at initialization time and then never modified, so
780 // it can be iterated on any thread.
781 LazyInitializedOnce
<const AutoTArray
<RefPtr
<Client
>, Client::TYPE_MAX
>>
784 using ClientTypesArray
= AutoTArray
<Client::Type
, Client::TYPE_MAX
>;
785 LazyInitializedOnce
<const ClientTypesArray
> mAllClientTypes
;
786 LazyInitializedOnce
<const ClientTypesArray
> mAllClientTypesExceptLS
;
788 // This object isn't protected by any mutex but it is only ever touched on
790 InitializationInfo mInitializationInfo
;
792 const nsString mBasePath
;
793 const nsString mStorageName
;
794 LazyInitializedOnce
<const nsString
> mIndexedDBPath
;
795 LazyInitializedOnce
<const nsString
> mStoragePath
;
796 LazyInitializedOnce
<const nsString
> mStorageArchivesPath
;
797 LazyInitializedOnce
<const nsString
> mPermanentStoragePath
;
798 LazyInitializedOnce
<const nsString
> mTemporaryStoragePath
;
799 LazyInitializedOnce
<const nsString
> mDefaultStoragePath
;
800 LazyInitializedOnce
<const nsString
> mPrivateStoragePath
;
801 LazyInitializedOnce
<const nsString
> mToBeRemovedStoragePath
;
803 uint64_t mTemporaryStorageLimit
;
804 uint64_t mTemporaryStorageUsage
;
805 int64_t mNextDirectoryLockId
;
806 uint64_t mShutdownStorageOpCount
;
807 bool mStorageInitialized
;
808 bool mTemporaryStorageInitialized
;
809 bool mTemporaryStorageInitializedInternal
;
813 } // namespace mozilla::dom::quota
815 #endif /* mozilla_dom_quota_quotamanager_h__ */