diff options
Diffstat (limited to 'dom/cache/QuotaClientImpl.h')
-rw-r--r-- | dom/cache/QuotaClientImpl.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/dom/cache/QuotaClientImpl.h b/dom/cache/QuotaClientImpl.h new file mode 100644 index 0000000000..e9ba6aff19 --- /dev/null +++ b/dom/cache/QuotaClientImpl.h @@ -0,0 +1,149 @@ +/* -*- 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: + using GroupAndOrigin = quota::GroupAndOrigin; + using PersistenceType = quota::PersistenceType; + using UsageInfo = quota::UsageInfo; + + CacheQuotaClient(); + + static CacheQuotaClient* Get(); + + virtual Type GetType() override; + + virtual Result<UsageInfo, nsresult> InitOrigin( + PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin, + const AtomicBool& aCanceled) override; + + virtual nsresult InitOriginWithoutTracking( + PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin, + const AtomicBool& aCanceled) override; + + virtual Result<UsageInfo, nsresult> GetUsageForOrigin( + PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin, + const AtomicBool& aCanceled) override; + + virtual void OnOriginClearCompleted(PersistenceType aPersistenceType, + const nsACString& aOrigin) 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. + CACHE_TRY(aCommitHook()); + + return NS_OK; + } + + { + MutexAutoLock lock(mDirPaddingFileMutex); + + // 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()); + + CACHE_TRY( + ToResult(LockedDirectoryPaddingFinalizeWrite(aBaseDir)) + .orElse([&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{}; + })); + } + + return NS_OK; + } + + nsresult RestorePaddingFileInternal(nsIFile* aBaseDir, + mozIStorageConnection* aConn); + + nsresult WipePaddingFileInternal(const QuotaInfo& aQuotaInfo, + nsIFile* aBaseDir); + + private: + ~CacheQuotaClient(); + + void InitiateShutdown() override; + bool IsShutdownCompleted() const override; + nsCString GetShutdownStatus() const override; + void ForceKillActors() override; + void FinalizeShutdown() override; + + Result<UsageInfo, nsresult> GetUsageForOriginInternal( + PersistenceType aPersistenceType, const GroupAndOrigin& aGroupAndOrigin, + const AtomicBool& aCanceled, bool aInitializing); + + 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 |