tor-browser

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

MaybeDiscarded.h (4430B)


      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 mozilla_dom_MaybeDiscarded_h
      8 #define mozilla_dom_MaybeDiscarded_h
      9 
     10 #include "mozilla/RefPtr.h"
     11 
     12 namespace mozilla::dom {
     13 
     14 // Wrapper type for a WindowContext or BrowsingContext instance which may be
     15 // discarded, and thus unavailable in the current process. This type is used to
     16 // pass WindowContext and BrowsingContext instances over IPC, as they may be
     17 // discarded in the receiving process.
     18 //
     19 // A MaybeDiscarded can generally be implicitly converted to from a
     20 // BrowsingContext* or WindowContext*, but requires an explicit check of
     21 // |IsDiscarded| and call to |get| to read from.
     22 template <typename T>
     23 class MaybeDiscarded {
     24 public:
     25  MaybeDiscarded() = default;
     26  MaybeDiscarded(MaybeDiscarded<T>&&) = default;
     27  MaybeDiscarded(const MaybeDiscarded<T>&) = default;
     28 
     29  // Construct from raw pointers and |nullptr|.
     30  MOZ_IMPLICIT MaybeDiscarded(T* aRawPtr)
     31      : mId(aRawPtr ? aRawPtr->Id() : 0), mPtr(aRawPtr) {}
     32  MOZ_IMPLICIT MaybeDiscarded(decltype(nullptr)) {}
     33 
     34  // Construct from |RefPtr<I>|
     35  template <typename I,
     36            typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
     37  MOZ_IMPLICIT MaybeDiscarded(RefPtr<I>&& aPtr)
     38      : mId(aPtr ? aPtr->Id() : 0), mPtr(std::move(aPtr)) {}
     39  template <typename I,
     40            typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
     41  MOZ_IMPLICIT MaybeDiscarded(const RefPtr<I>& aPtr)
     42      : mId(aPtr ? aPtr->Id() : 0), mPtr(aPtr) {}
     43 
     44  // Basic assignment operators.
     45  MaybeDiscarded<T>& operator=(const MaybeDiscarded<T>&) = default;
     46  MaybeDiscarded<T>& operator=(MaybeDiscarded<T>&&) = default;
     47  MaybeDiscarded<T>& operator=(decltype(nullptr)) {
     48    mId = 0;
     49    mPtr = nullptr;
     50    return *this;
     51  }
     52  MaybeDiscarded<T>& operator=(T* aRawPtr) {
     53    mId = aRawPtr ? aRawPtr->Id() : 0;
     54    mPtr = aRawPtr;
     55    return *this;
     56  }
     57  template <typename I>
     58  MaybeDiscarded<T>& operator=(const RefPtr<I>& aRhs) {
     59    mId = aRhs ? aRhs->Id() : 0;
     60    mPtr = aRhs;
     61    return *this;
     62  }
     63  template <typename I>
     64  MaybeDiscarded<T>& operator=(RefPtr<I>&& aRhs) {
     65    mId = aRhs ? aRhs->Id() : 0;
     66    mPtr = std::move(aRhs);
     67    return *this;
     68  }
     69 
     70  // Validate that the value is neither discarded nor null.
     71  bool IsNullOrDiscarded() const { return !mPtr || mPtr->IsDiscarded(); }
     72  bool IsDiscarded() const { return IsNullOrDiscarded() && !IsNull(); }
     73  bool IsNull() const { return mId == 0; }
     74 
     75  explicit operator bool() const { return !IsNullOrDiscarded(); }
     76 
     77  // Extract the wrapped |T|. Must not be called on a discarded |T|.
     78  T* get() const {
     79    MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
     80    return mPtr.get();
     81  }
     82  already_AddRefed<T> forget() {
     83    MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
     84    return mPtr.forget();
     85  }
     86 
     87  T* operator->() const {
     88    MOZ_ASSERT(!IsNull());
     89    return get();
     90  }
     91 
     92  // Like "get", but gets the "Canonical" version of the type. This method may
     93  // only be called in the parent process.
     94  auto get_canonical() const -> decltype(get()->Canonical()) {
     95    if (get()) {
     96      return get()->Canonical();
     97    } else {
     98      return nullptr;
     99    }
    100  }
    101 
    102  // The ID for the context wrapped by this MaybeDiscarded. This ID comes from a
    103  // remote process, and should generally only be used for logging. A
    104  // BrowsingContext with this ID may not exist in the current process.
    105  uint64_t ContextId() const { return mId; }
    106 
    107  // Tries to get the wrapped value, disregarding discarded status.
    108  // This may return |nullptr| for a non-null |MaybeDiscarded|, in the case that
    109  // the target is no longer available in this process.
    110  T* GetMaybeDiscarded() const { return mPtr.get(); }
    111 
    112  // Clear the value to a discarded state with the given ID.
    113  void SetDiscarded(uint64_t aId) {
    114    mId = aId;
    115    mPtr = nullptr;
    116  }
    117 
    118  // Comparison operators required by IPDL
    119  bool operator==(const MaybeDiscarded<T>& aRhs) const {
    120    return mId == aRhs.mId && mPtr == aRhs.mPtr;
    121  }
    122  bool operator!=(const MaybeDiscarded<T>& aRhs) const {
    123    return !operator==(aRhs);
    124  }
    125 
    126 private:
    127  uint64_t mId = 0;
    128  RefPtr<T> mPtr;
    129 };
    130 
    131 }  // namespace mozilla::dom
    132 
    133 #endif  // mozilla_dom_MaybeDiscarded_h