summaryrefslogtreecommitdiffstats
path: root/dom/cache/QuotaClientImpl.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/cache/QuotaClientImpl.h')
-rw-r--r--dom/cache/QuotaClientImpl.h145
1 files changed, 145 insertions, 0 deletions
diff --git a/dom/cache/QuotaClientImpl.h b/dom/cache/QuotaClientImpl.h
new file mode 100644
index 0000000000..de48119431
--- /dev/null
+++ b/dom/cache/QuotaClientImpl.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_cache_QuotaClientImpl_h
+#define mozilla_dom_cache_QuotaClientImpl_h
+
+#include "CacheCipherKeyManager.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/dom/QMResult.h"
+#include "mozilla/dom/cache/QuotaClient.h"
+#include "mozilla/dom/cache/FileUtils.h"
+#include "mozilla/dom/cache/Types.h"
+#include "mozilla/dom/quota/ResultExtensions.h"
+
+namespace mozilla::dom::cache {
+
+class CacheQuotaClient final : public quota::Client {
+ static CacheQuotaClient* sInstance;
+
+ public:
+ using OriginMetadata = quota::OriginMetadata;
+ using PersistenceType = quota::PersistenceType;
+ using UsageInfo = quota::UsageInfo;
+
+ CacheQuotaClient();
+
+ static CacheQuotaClient* Get();
+
+ virtual Type GetType() override;
+
+ virtual Result<UsageInfo, nsresult> InitOrigin(
+ PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
+ const AtomicBool& aCanceled) override;
+
+ virtual nsresult InitOriginWithoutTracking(
+ PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
+ const AtomicBool& aCanceled) override;
+
+ virtual Result<UsageInfo, nsresult> GetUsageForOrigin(
+ PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
+ const AtomicBool& aCanceled) override;
+
+ virtual void OnOriginClearCompleted(PersistenceType aPersistenceType,
+ const nsACString& aOrigin) override;
+
+ void OnRepositoryClearCompleted(PersistenceType aPersistenceType) override;
+
+ virtual void ReleaseIOThreadObjects() override;
+
+ void AbortOperationsForLocks(
+ const DirectoryLockIdTable& aDirectoryLockIds) override;
+
+ virtual void AbortOperationsForProcess(
+ ContentParentId aContentParentId) override;
+
+ virtual void AbortAllOperations() override;
+
+ virtual void StartIdleMaintenance() override;
+
+ virtual void StopIdleMaintenance() override;
+
+ nsresult UpgradeStorageFrom2_0To2_1(nsIFile* aDirectory) override;
+
+ template <typename Callable>
+ nsresult MaybeUpdatePaddingFileInternal(nsIFile& aBaseDir,
+ mozIStorageConnection& aConn,
+ const int64_t aIncreaseSize,
+ const int64_t aDecreaseSize,
+ Callable&& aCommitHook) {
+ MOZ_ASSERT(!NS_IsMainThread());
+ MOZ_DIAGNOSTIC_ASSERT(aIncreaseSize >= 0);
+ MOZ_DIAGNOSTIC_ASSERT(aDecreaseSize >= 0);
+
+ // Temporary should be removed at the end of each action. If not, it means
+ // the failure happened.
+ const bool temporaryPaddingFileExist =
+ DirectoryPaddingFileExists(aBaseDir, DirPaddingFile::TMP_FILE);
+
+ if (aIncreaseSize == aDecreaseSize && !temporaryPaddingFileExist) {
+ // Early return here, since most cache actions won't modify padding size.
+ QM_TRY(MOZ_TO_RESULT(aCommitHook()));
+
+ return NS_OK;
+ }
+
+ // Don't delete the temporary padding file in case of an error to force the
+ // next action recalculate the padding size.
+ QM_TRY(MOZ_TO_RESULT(
+ UpdateDirectoryPaddingFile(aBaseDir, aConn, aIncreaseSize,
+ aDecreaseSize, temporaryPaddingFileExist)));
+
+ // Don't delete the temporary padding file in case of an error to force the
+ // next action recalculate the padding size.
+ QM_TRY(MOZ_TO_RESULT(aCommitHook()));
+
+ QM_WARNONLY_TRY(MOZ_TO_RESULT(DirectoryPaddingFinalizeWrite(aBaseDir)),
+ ([&aBaseDir](const nsresult) {
+ // Force restore file next time.
+ QM_WARNONLY_TRY(QM_TO_RESULT(DirectoryPaddingDeleteFile(
+ aBaseDir, DirPaddingFile::FILE)));
+
+ // Ensure that we are able to force the padding file to
+ // be restored.
+ MOZ_ASSERT(DirectoryPaddingFileExists(
+ aBaseDir, DirPaddingFile::TMP_FILE));
+
+ // Since both the body file and header have been stored
+ // in the file-system, just make the action be resolve
+ // and let the padding file be restored in the next
+ // action.
+ }));
+
+ return NS_OK;
+ }
+
+ nsresult RestorePaddingFileInternal(nsIFile* aBaseDir,
+ mozIStorageConnection* aConn);
+
+ nsresult WipePaddingFileInternal(
+ const CacheDirectoryMetadata& aDirectoryMetadata, nsIFile* aBaseDir);
+
+ RefPtr<CipherKeyManager> GetOrCreateCipherKeyManager(
+ const quota::PrincipalMetadata& aMetadata);
+
+ private:
+ ~CacheQuotaClient();
+
+ void InitiateShutdown() override;
+ bool IsShutdownCompleted() const override;
+ nsCString GetShutdownStatus() const override;
+ void ForceKillActors() override;
+ void FinalizeShutdown() override;
+
+ // Should always be accessed from QM IO thread.
+ nsTHashMap<nsCStringHashKey, RefPtr<CipherKeyManager>> mCipherKeyManagers;
+
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheQuotaClient, override)
+};
+
+} // namespace mozilla::dom::cache
+
+#endif // mozilla_dom_cache_QuotaClientImpl_h