mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	Depends on D180296 Differential Revision: https://phabricator.services.mozilla.com/D180297
		
			
				
	
	
		
			145 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- 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
 |