1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 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/FileUtils.h"
#include "mozilla/dom/cache/QuotaClient.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(
const OriginMetadata& aOriginMetadata) 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
|