tor-browser

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

DDLifetimes.h (4592B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      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 DDLifetimes_h_
      8 #define DDLifetimes_h_
      9 
     10 #include <type_traits>
     11 
     12 #include "DDLifetime.h"
     13 #include "DDLoggedTypeTraits.h"
     14 #include "nsClassHashtable.h"
     15 #include "nsTArray.h"
     16 
     17 namespace mozilla {
     18 
     19 // Managed list of lifetimes.
     20 class DDLifetimes {
     21 public:
     22  // DDLifetime for a given aObject, that exists at the aIndex time;
     23  // otherwise nullptr.
     24  DDLifetime* FindLifetime(const DDLogObject& aObject,
     25                           const DDMessageIndex& aIndex);
     26 
     27  // DDLifetime for a given aObject, that exists at the aIndex time;
     28  // otherwise nullptr.
     29  const DDLifetime* FindLifetime(const DDLogObject& aObject,
     30                                 const DDMessageIndex& aIndex) const;
     31 
     32  // Create a lifetime with the given object and construction index&time.
     33  DDLifetime& CreateLifetime(const DDLogObject& aObject, DDMessageIndex aIndex,
     34                             const DDTimeStamp& aConstructionTimeStamp);
     35 
     36  // Remove an existing lifetime (assumed to just have been found by
     37  // FindLifetime()).
     38  void RemoveLifetime(const DDLifetime* aLifetime);
     39 
     40  // Remove all lifetimes associated with the given HTMLMediaElement.
     41  void RemoveLifetimesFor(const dom::HTMLMediaElement* aMediaElement);
     42 
     43  // Remove all lifetimes.
     44  void Clear();
     45 
     46  // Visit all lifetimes associated with an HTMLMediaElement and run
     47  // `aF(const DDLifetime&)` on each one.
     48  // If aOnlyHTMLMediaElement is true, only run aF once of that element.
     49  template <typename F>
     50  void Visit(const dom::HTMLMediaElement* aMediaElement, F&& aF,
     51             bool aOnlyHTMLMediaElement = false) const {
     52    for (const auto& lifetimes : mLifetimes.Values()) {
     53      for (const DDLifetime& lifetime : *lifetimes) {
     54        if (lifetime.mMediaElement == aMediaElement) {
     55          if (aOnlyHTMLMediaElement) {
     56            if (lifetime.mObject.Pointer() == aMediaElement &&
     57                lifetime.mObject.TypeName() ==
     58                    DDLoggedTypeTraits<dom::HTMLMediaElement>::Name()) {
     59              aF(lifetime);
     60              break;
     61            }
     62            continue;
     63          }
     64          static_assert(std::is_same_v<decltype(aF(lifetime)), void>, "");
     65          aF(lifetime);
     66        }
     67      }
     68    }
     69  }
     70 
     71  // Visit all lifetimes associated with an HTMLMediaElement and run
     72  // `aF(const DDLifetime&)` on each one.
     73  // If aF() returns false, the loop continues.
     74  // If aF() returns true, the loop stops, and true is returned immediately.
     75  // If all aF() calls have returned false, false is returned at the end.
     76  template <typename F>
     77  bool VisitBreakable(const dom::HTMLMediaElement* aMediaElement,
     78                      F&& aF) const {
     79    for (const auto& lifetimes : mLifetimes.Values()) {
     80      for (const DDLifetime& lifetime : *lifetimes) {
     81        if (lifetime.mMediaElement == aMediaElement) {
     82          static_assert(std::is_same_v<decltype(aF(lifetime)), bool>, "");
     83          if (aF(lifetime)) {
     84            return true;
     85          }
     86        }
     87      }
     88    }
     89    return false;
     90  }
     91 
     92  size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
     93 
     94 private:
     95  // Hashtable key to use for each DDLogObject.
     96  class DDLogObjectHashKey : public PLDHashEntryHdr {
     97   public:
     98    typedef const DDLogObject& KeyType;
     99    typedef const DDLogObject* KeyTypePointer;
    100 
    101    explicit DDLogObjectHashKey(KeyTypePointer aKey) : mValue(*aKey) {}
    102    DDLogObjectHashKey(const DDLogObjectHashKey& aToCopy)
    103        : mValue(aToCopy.mValue) {}
    104    ~DDLogObjectHashKey() = default;
    105 
    106    KeyType GetKey() const { return mValue; }
    107    bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
    108 
    109    static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
    110    static PLDHashNumber HashKey(KeyTypePointer aKey) {
    111      return HashBytes(aKey, sizeof(DDLogObject));
    112    }
    113    enum { ALLOW_MEMMOVE = true };
    114 
    115   private:
    116    const DDLogObject mValue;
    117  };
    118 
    119  // Array of all DDLifetimes for a given DDLogObject; they should be
    120  // distinguished by their construction&destruction times.
    121  using LifetimesForObject = nsTArray<DDLifetime>;
    122 
    123  // For each DDLogObject, we store an array of all objects that have used this
    124  // pointer and type.
    125  nsClassHashtable<DDLogObjectHashKey, LifetimesForObject> mLifetimes;
    126 };
    127 
    128 }  // namespace mozilla
    129 
    130 #endif  // DDLifetimes_h_