tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

OpenClientDirectoryUtils.h (6081B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_QUOTA_OPENCLIENTDIRECTORYUTILS_H_
      8 #define DOM_QUOTA_OPENCLIENTDIRECTORYUTILS_H_
      9 
     10 #include <functional>
     11 
     12 #include "mozilla/MozPromise.h"
     13 #include "mozilla/RefPtr.h"
     14 #include "mozilla/dom/quota/ArtificialFailure.h"
     15 #include "mozilla/dom/quota/ClientDirectoryLock.h"
     16 #include "mozilla/dom/quota/ClientDirectoryLockHandle.h"
     17 #include "mozilla/dom/quota/DirectoryLock.h"
     18 #include "mozilla/dom/quota/DirectoryLockInlines.h"
     19 #include "mozilla/dom/quota/ForwardDecls.h"
     20 #include "mozilla/dom/quota/QuotaManager.h"
     21 #include "mozilla/dom/quota/UniversalDirectoryLock.h"
     22 
     23 namespace mozilla::dom::quota {
     24 
     25 template <typename UninitChecker, typename PromiseArrayIter>
     26 RefPtr<UniversalDirectoryLock> CreateDirectoryLockForInitialization(
     27    QuotaManager& aQuotaManager, const PersistenceScope& aPersistenceScope,
     28    const OriginScope& aOriginScope,
     29    const ClientStorageScope& aClientStorageScope,
     30    const bool aAlreadyInitialized, UninitChecker&& aUninitChecker,
     31    PromiseArrayIter&& aPromiseArrayIter) {
     32  RefPtr<UniversalDirectoryLock> directoryLock =
     33      aQuotaManager.CreateDirectoryLockInternal(aPersistenceScope, aOriginScope,
     34                                                aClientStorageScope,
     35                                                /* aExclusive */ false);
     36 
     37  auto prepareInfo = directoryLock->Prepare();
     38 
     39  if (aAlreadyInitialized &&
     40      !std::forward<UninitChecker>(aUninitChecker)(prepareInfo)) {
     41    return nullptr;
     42  }
     43 
     44  auto iter = std::forward<PromiseArrayIter>(aPromiseArrayIter);
     45  *iter = directoryLock->Acquire(std::move(prepareInfo));
     46  ++iter;
     47 
     48  return directoryLock;
     49 }
     50 
     51 template <typename Callable>
     52 class MaybeInitializeHelper final {
     53 public:
     54  MaybeInitializeHelper(RefPtr<UniversalDirectoryLock> aDirectoryLock,
     55                        Callable&& aCallable)
     56      : mDirectoryLock(std::move(aDirectoryLock)),
     57        mCallable(std::move(aCallable)) {}
     58 
     59  RefPtr<BoolPromise> operator()(
     60      const BoolPromise::ResolveOrRejectValue& aValue) {
     61    if (aValue.IsReject()) {
     62      SafeDropDirectoryLockIfNotDropped(mDirectoryLock);
     63 
     64      return BoolPromise::CreateAndReject(aValue.RejectValue(), __func__);
     65    }
     66 
     67    if (!mDirectoryLock) {
     68      return BoolPromise::CreateAndResolve(true, __func__);
     69    }
     70 
     71    return mCallable(std::move(mDirectoryLock));
     72  }
     73 
     74 private:
     75  RefPtr<UniversalDirectoryLock> mDirectoryLock;
     76  Callable mCallable;
     77 };
     78 
     79 template <typename Callable>
     80 auto MaybeInitialize(RefPtr<UniversalDirectoryLock> aDirectoryLock,
     81                     Callable&& aCallable) {
     82  return MaybeInitializeHelper(std::move(aDirectoryLock),
     83                               std::forward<Callable>(aCallable));
     84 }
     85 
     86 auto MaybeInitialize(RefPtr<UniversalDirectoryLock> aDirectoryLock,
     87                     RefPtr<QuotaManager> aQuotaManager,
     88                     RefPtr<BoolPromise> (QuotaManager::*aMethod)(
     89                         RefPtr<UniversalDirectoryLock>)) {
     90  return MaybeInitializeHelper(
     91      std::move(aDirectoryLock),
     92      [quotaManager = std::move(aQuotaManager),
     93       method = aMethod](RefPtr<UniversalDirectoryLock> aDirectoryLock) {
     94        return (quotaManager->*method)(std::move(aDirectoryLock));
     95      });
     96 }
     97 
     98 // XXX: Consider renaming the finalization class and function below to make
     99 // their purpose more specific
    100 template <typename Callable>
    101 class MaybeFinalizeHelper final {
    102 public:
    103  MaybeFinalizeHelper(RefPtr<ClientDirectoryLock> aClientDirectoryLock,
    104                      RefPtr<UniversalDirectoryLock> aFirstAccessDirectoryLock,
    105                      RefPtr<UniversalDirectoryLock> aLastAccessDirectoryLock,
    106                      Callable&& aCallable)
    107      : mClientDirectoryLock(std::move(aClientDirectoryLock)),
    108        mFirstAccessDirectoryLock(std::move(aFirstAccessDirectoryLock)),
    109        mLastAccessDirectoryLock(std::move(aLastAccessDirectoryLock)),
    110        mCallable(std::move(aCallable)) {}
    111 
    112  RefPtr<QuotaManager::ClientDirectoryLockHandlePromise> operator()(
    113      const BoolPromise::ResolveOrRejectValue& aValue) {
    114    if (aValue.IsReject()) {
    115      DropDirectoryLockIfNotDropped(mClientDirectoryLock);
    116      DropDirectoryLockIfNotDropped(mFirstAccessDirectoryLock);
    117      DropDirectoryLockIfNotDropped(mLastAccessDirectoryLock);
    118 
    119      return QuotaManager::ClientDirectoryLockHandlePromise::CreateAndReject(
    120          aValue.RejectValue(), __func__);
    121    }
    122 
    123    QM_TRY(ArtificialFailure(
    124               nsIQuotaArtificialFailure::CATEGORY_OPEN_CLIENT_DIRECTORY),
    125           [this](nsresult rv) {
    126             DropDirectoryLock(mClientDirectoryLock);
    127             DropDirectoryLock(mFirstAccessDirectoryLock);
    128             DropDirectoryLock(mLastAccessDirectoryLock);
    129 
    130             return QuotaManager::ClientDirectoryLockHandlePromise::
    131                 CreateAndReject(rv, __func__);
    132           });
    133 
    134    return mCallable(std::move(mClientDirectoryLock),
    135                     std::move(mFirstAccessDirectoryLock),
    136                     std::move(mLastAccessDirectoryLock));
    137  }
    138 
    139 private:
    140  RefPtr<ClientDirectoryLock> mClientDirectoryLock;
    141  RefPtr<UniversalDirectoryLock> mFirstAccessDirectoryLock;
    142  RefPtr<UniversalDirectoryLock> mLastAccessDirectoryLock;
    143  Callable mCallable;
    144 };
    145 
    146 template <typename Callable>
    147 auto MaybeFinalize(RefPtr<ClientDirectoryLock> aClientDirectoryLock,
    148                   RefPtr<UniversalDirectoryLock> aFirstAccessDirectoryLock,
    149                   RefPtr<UniversalDirectoryLock> aLastAccessDirectoryLock,
    150                   Callable&& aCallable) {
    151  return MaybeFinalizeHelper(
    152      std::move(aClientDirectoryLock), std::move(aFirstAccessDirectoryLock),
    153      std::move(aLastAccessDirectoryLock), std::forward<Callable>(aCallable));
    154 }
    155 
    156 }  // namespace mozilla::dom::quota
    157 
    158 #endif  // DOM_QUOTA_OPENCLIENTDIRECTORYUTILS_H_