2020-04-15 02:51:44 +03:00
|
|
|
/* -*- 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 "mozilla/dom/cache/QuotaClient.h"
|
|
|
|
#include "mozilla/dom/cache/FileUtils.h"
|
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
namespace cache {
|
|
|
|
|
|
|
|
class CacheQuotaClient final : public quota::Client {
|
|
|
|
static CacheQuotaClient* sInstance;
|
|
|
|
|
|
|
|
public:
|
2021-02-12 17:03:28 +03:00
|
|
|
using OriginMetadata = quota::OriginMetadata;
|
2020-04-15 02:51:44 +03:00
|
|
|
using PersistenceType = quota::PersistenceType;
|
|
|
|
using UsageInfo = quota::UsageInfo;
|
|
|
|
|
|
|
|
CacheQuotaClient();
|
|
|
|
|
|
|
|
static CacheQuotaClient* Get();
|
|
|
|
|
|
|
|
virtual Type GetType() override;
|
2020-06-25 12:31:39 +03:00
|
|
|
|
|
|
|
virtual Result<UsageInfo, nsresult> InitOrigin(
|
2021-02-12 17:03:28 +03:00
|
|
|
PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
|
2020-10-20 14:46:31 +03:00
|
|
|
const AtomicBool& aCanceled) override;
|
2020-06-25 12:31:39 +03:00
|
|
|
|
|
|
|
virtual nsresult InitOriginWithoutTracking(
|
2021-02-12 17:03:28 +03:00
|
|
|
PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
|
2020-10-20 14:46:31 +03:00
|
|
|
const AtomicBool& aCanceled) override;
|
2020-04-15 02:51:44 +03:00
|
|
|
|
2020-06-25 11:34:43 +03:00
|
|
|
virtual Result<UsageInfo, nsresult> GetUsageForOrigin(
|
2021-02-12 17:03:28 +03:00
|
|
|
PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
|
2020-10-20 14:46:31 +03:00
|
|
|
const AtomicBool& aCanceled) override;
|
2020-04-15 02:51:44 +03:00
|
|
|
|
|
|
|
virtual void OnOriginClearCompleted(PersistenceType aPersistenceType,
|
|
|
|
const nsACString& aOrigin) override;
|
|
|
|
|
|
|
|
virtual void ReleaseIOThreadObjects() override;
|
|
|
|
|
2020-12-09 11:13:44 +03:00
|
|
|
void AbortOperationsForLocks(
|
|
|
|
const DirectoryLockIdTable& aDirectoryLockIds) override;
|
2020-04-15 02:51:44 +03:00
|
|
|
|
|
|
|
virtual void AbortOperationsForProcess(
|
|
|
|
ContentParentId aContentParentId) override;
|
|
|
|
|
2020-12-02 19:38:07 +03:00
|
|
|
virtual void AbortAllOperations() override;
|
|
|
|
|
2020-04-15 02:51:44 +03:00
|
|
|
virtual void StartIdleMaintenance() override;
|
|
|
|
|
|
|
|
virtual void StopIdleMaintenance() override;
|
|
|
|
|
|
|
|
nsresult UpgradeStorageFrom2_0To2_1(nsIFile* aDirectory) override;
|
|
|
|
|
|
|
|
template <typename Callable>
|
2021-01-18 11:52:06 +03:00
|
|
|
nsresult MaybeUpdatePaddingFileInternal(nsIFile& aBaseDir,
|
|
|
|
mozIStorageConnection& aConn,
|
2020-04-15 02:51:44 +03:00
|
|
|
const int64_t aIncreaseSize,
|
|
|
|
const int64_t aDecreaseSize,
|
2021-01-18 11:52:06 +03:00
|
|
|
Callable&& aCommitHook) {
|
2020-04-15 02:51:44 +03:00
|
|
|
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.
|
2021-01-18 11:52:06 +03:00
|
|
|
const bool temporaryPaddingFileExist =
|
|
|
|
DirectoryPaddingFileExists(aBaseDir, DirPaddingFile::TMP_FILE);
|
2020-04-15 02:51:44 +03:00
|
|
|
|
|
|
|
if (aIncreaseSize == aDecreaseSize && !temporaryPaddingFileExist) {
|
|
|
|
// Early return here, since most cache actions won't modify padding size.
|
2021-01-18 11:52:06 +03:00
|
|
|
CACHE_TRY(aCommitHook());
|
|
|
|
|
|
|
|
return NS_OK;
|
2020-04-15 02:51:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
MutexAutoLock lock(mDirPaddingFileMutex);
|
2021-01-18 11:52:06 +03:00
|
|
|
|
|
|
|
// Don't delete the temporary padding file in case of an error to force
|
|
|
|
// the next action recalculate the padding size.
|
|
|
|
CACHE_TRY(LockedUpdateDirectoryPaddingFile(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.
|
|
|
|
CACHE_TRY(aCommitHook());
|
|
|
|
|
2021-03-24 15:27:53 +03:00
|
|
|
QM_TRY(QM_OR_ELSE_WARN(
|
|
|
|
ToResult(LockedDirectoryPaddingFinalizeWrite(aBaseDir)),
|
|
|
|
([&aBaseDir](const nsresult) -> Result<Ok, nsresult> {
|
|
|
|
// Force restore file next time.
|
|
|
|
Unused << LockedDirectoryPaddingDeleteFile(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 Ok{};
|
|
|
|
})));
|
2020-04-15 02:51:44 +03:00
|
|
|
}
|
|
|
|
|
2021-01-18 11:52:06 +03:00
|
|
|
return NS_OK;
|
2020-04-15 02:51:44 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
nsresult RestorePaddingFileInternal(nsIFile* aBaseDir,
|
|
|
|
mozIStorageConnection* aConn);
|
|
|
|
|
|
|
|
nsresult WipePaddingFileInternal(const QuotaInfo& aQuotaInfo,
|
|
|
|
nsIFile* aBaseDir);
|
|
|
|
|
|
|
|
private:
|
|
|
|
~CacheQuotaClient();
|
|
|
|
|
2020-11-26 12:20:03 +03:00
|
|
|
void InitiateShutdown() override;
|
|
|
|
bool IsShutdownCompleted() const override;
|
2020-11-30 13:40:59 +03:00
|
|
|
nsCString GetShutdownStatus() const override;
|
2020-11-26 12:20:03 +03:00
|
|
|
void ForceKillActors() override;
|
|
|
|
void FinalizeShutdown() override;
|
|
|
|
|
2020-04-15 02:51:44 +03:00
|
|
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheQuotaClient, override)
|
|
|
|
|
|
|
|
// Mutex lock to protect directroy padding files. It should only be acquired
|
|
|
|
// in DOM Cache IO threads and Quota IO thread.
|
|
|
|
mozilla::Mutex mDirPaddingFileMutex;
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace cache
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif // mozilla_dom_cache_QuotaClientImpl_h
|