tor-browser

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

FileSystemHelpers.h (4144B)


      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
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_FS_SHARED_FILESYSTEMHELPERS_H_
      8 #define DOM_FS_SHARED_FILESYSTEMHELPERS_H_
      9 
     10 #include "FileSystemTypes.h"
     11 #include "mozilla/RefPtr.h"
     12 
     13 namespace mozilla::dom::fs {
     14 
     15 // XXX Consider moving this class template to MFBT.
     16 
     17 // A wrapper class template on top of the RefPtr. The RefPtr provides us the
     18 // automatic reference counting of objects with AddRef() and Release() methods.
     19 // `Registered` provides automatic registration counting of objects with
     20 // Register() and Unregister() methods. Registration counting works similarly
     21 // as reference counting, but objects are not deleted when the number of
     22 // registrations drops to zero (that's managed by reference counting). Instead,
     23 // an object can trigger an asynchronous close operation which still needs to
     24 // hold and use the referenced object. Example:
     25 //
     26 // using BoolPromise = MozPromise<bool, nsresult, false>;
     27 //
     28 // class MyObject {
     29 //  public:
     30 //   NS_INLINE_DECL_REFCOUNTING(MyObject)
     31 //
     32 //   void Register() {
     33 //     mRegCnt++;
     34 //   }
     35 //
     36 //   void Unregister() {
     37 //     mRegCnt--;
     38 //     if (mRegCnt == 0) {
     39 //       BeginClose();
     40 //     }
     41 //   }
     42 //
     43 //  private:
     44 //   RefPtr<BoolPromise> BeginClose() {
     45 //     return InvokeAsync(mIOTaskQueue, __func__,
     46 //                []() {
     47 //                  return BoolPromise::CreateAndResolve(true, __func__);
     48 //                })
     49 //         ->Then(GetCurrentSerialEventTarget(), __func__,
     50 //                [self = RefPtr<MyObject>(this)](
     51 //                    const BoolPromise::ResolveOrRejectValue&) {
     52 //                  return self->mIOTaskQueue->BeginShutdown();
     53 //                })
     54 //         ->Then(GetCurrentSerialEventTarget(), __func__,
     55 //                [self = RefPtr<MyObject>(this)](
     56 //                    const ShutdownPromise::ResolveOrRejectValue&) {
     57 //                  return BoolPromise::CreateAndResolve(true, __func__);
     58 //                });
     59 //   }
     60 //
     61 //   RefPtr<TaskQueue> mIOTaskQueue;
     62 //   uint32_t mRegCnt = 0;
     63 // };
     64 
     65 template <class T>
     66 class Registered {
     67 private:
     68  RefPtr<T> mObject;
     69 
     70 public:
     71  ~Registered() {
     72    if (mObject) {
     73      mObject->Unregister();
     74    }
     75  }
     76 
     77  Registered() = default;
     78 
     79  Registered(const Registered& aOther) : mObject(aOther.mObject) {
     80    mObject->Register();
     81  }
     82 
     83  Registered(Registered&& aOther) noexcept = default;
     84 
     85  MOZ_IMPLICIT Registered(RefPtr<T> aObject) : mObject(std::move(aObject)) {
     86    if (mObject) {
     87      mObject->Register();
     88    }
     89  }
     90 
     91  Registered<T>& operator=(decltype(nullptr)) {
     92    RefPtr<T> oldObject = std::move(mObject);
     93    mObject = nullptr;
     94    if (oldObject) {
     95      oldObject->Unregister();
     96    }
     97    return *this;
     98  }
     99 
    100  Registered<T>& operator=(const Registered<T>& aRhs) {
    101    if (aRhs.mObject) {
    102      aRhs.mObject->Register();
    103    }
    104    RefPtr<T> oldObject = std::move(mObject);
    105    mObject = aRhs.mObject;
    106    if (oldObject) {
    107      oldObject->Unregister();
    108    }
    109    return *this;
    110  }
    111 
    112  Registered<T>& operator=(Registered<T>&& aRhs) noexcept {
    113    RefPtr<T> oldObject = std::move(mObject);
    114    mObject = std::move(aRhs.mObject);
    115    aRhs.mObject = nullptr;
    116    if (oldObject) {
    117      oldObject->Unregister();
    118    }
    119    return *this;
    120  }
    121 
    122  const RefPtr<T>& inspect() const { return mObject; }
    123 
    124  RefPtr<T> unwrap() {
    125    RefPtr<T> oldObject = std::move(mObject);
    126    mObject = nullptr;
    127    if (oldObject) {
    128      oldObject->Unregister();
    129    }
    130    return oldObject;
    131  }
    132 
    133  T* get() const { return mObject; }
    134 
    135  operator T*() const& { return get(); }
    136 
    137  T* operator->() const { return get(); }
    138 };
    139 
    140 // Spec says valid names don't include (os-dependent) path separators,
    141 // and is not equal to a dot . or two dots ..
    142 // We want to use the same validator from both child and parent.
    143 bool IsValidName(const fs::Name& aName);
    144 
    145 }  // namespace mozilla::dom::fs
    146 
    147 #endif  // DOM_FS_SHARED_FILESYSTEMHELPERS_H_