summaryrefslogtreecommitdiffstats
path: root/dom/media/doctor/DDLifetimes.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/doctor/DDLifetimes.h')
-rw-r--r--dom/media/doctor/DDLifetimes.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/dom/media/doctor/DDLifetimes.h b/dom/media/doctor/DDLifetimes.h
new file mode 100644
index 0000000000..3cfcafc995
--- /dev/null
+++ b/dom/media/doctor/DDLifetimes.h
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 DDLifetimes_h_
+#define DDLifetimes_h_
+
+#include <type_traits>
+
+#include "DDLifetime.h"
+#include "DDLoggedTypeTraits.h"
+#include "nsClassHashtable.h"
+#include "nsTArray.h"
+
+namespace mozilla {
+
+// Managed list of lifetimes.
+class DDLifetimes {
+ public:
+ // DDLifetime for a given aObject, that exists at the aIndex time;
+ // otherwise nullptr.
+ DDLifetime* FindLifetime(const DDLogObject& aObject,
+ const DDMessageIndex& aIndex);
+
+ // DDLifetime for a given aObject, that exists at the aIndex time;
+ // otherwise nullptr.
+ const DDLifetime* FindLifetime(const DDLogObject& aObject,
+ const DDMessageIndex& aIndex) const;
+
+ // Create a lifetime with the given object and construction index&time.
+ DDLifetime& CreateLifetime(const DDLogObject& aObject, DDMessageIndex aIndex,
+ const DDTimeStamp& aConstructionTimeStamp);
+
+ // Remove an existing lifetime (assumed to just have been found by
+ // FindLifetime()).
+ void RemoveLifetime(const DDLifetime* aLifetime);
+
+ // Remove all lifetimes associated with the given HTMLMediaElement.
+ void RemoveLifetimesFor(const dom::HTMLMediaElement* aMediaElement);
+
+ // Remove all lifetimes.
+ void Clear();
+
+ // Visit all lifetimes associated with an HTMLMediaElement and run
+ // `aF(const DDLifetime&)` on each one.
+ // If aOnlyHTMLMediaElement is true, only run aF once of that element.
+ template <typename F>
+ void Visit(const dom::HTMLMediaElement* aMediaElement, F&& aF,
+ bool aOnlyHTMLMediaElement = false) const {
+ for (const auto& lifetimes : mLifetimes.Values()) {
+ for (const DDLifetime& lifetime : *lifetimes) {
+ if (lifetime.mMediaElement == aMediaElement) {
+ if (aOnlyHTMLMediaElement) {
+ if (lifetime.mObject.Pointer() == aMediaElement &&
+ lifetime.mObject.TypeName() ==
+ DDLoggedTypeTraits<dom::HTMLMediaElement>::Name()) {
+ aF(lifetime);
+ break;
+ }
+ continue;
+ }
+ static_assert(std::is_same_v<decltype(aF(lifetime)), void>, "");
+ aF(lifetime);
+ }
+ }
+ }
+ }
+
+ // Visit all lifetimes associated with an HTMLMediaElement and run
+ // `aF(const DDLifetime&)` on each one.
+ // If aF() returns false, the loop continues.
+ // If aF() returns true, the loop stops, and true is returned immediately.
+ // If all aF() calls have returned false, false is returned at the end.
+ template <typename F>
+ bool VisitBreakable(const dom::HTMLMediaElement* aMediaElement,
+ F&& aF) const {
+ for (const auto& lifetimes : mLifetimes.Values()) {
+ for (const DDLifetime& lifetime : *lifetimes) {
+ if (lifetime.mMediaElement == aMediaElement) {
+ static_assert(std::is_same_v<decltype(aF(lifetime)), bool>, "");
+ if (aF(lifetime)) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const;
+
+ private:
+ // Hashtable key to use for each DDLogObject.
+ class DDLogObjectHashKey : public PLDHashEntryHdr {
+ public:
+ typedef const DDLogObject& KeyType;
+ typedef const DDLogObject* KeyTypePointer;
+
+ explicit DDLogObjectHashKey(KeyTypePointer aKey) : mValue(*aKey) {}
+ DDLogObjectHashKey(const DDLogObjectHashKey& aToCopy)
+ : mValue(aToCopy.mValue) {}
+ ~DDLogObjectHashKey() = default;
+
+ KeyType GetKey() const { return mValue; }
+ bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
+
+ static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
+ static PLDHashNumber HashKey(KeyTypePointer aKey) {
+ return HashBytes(aKey, sizeof(DDLogObject));
+ }
+ enum { ALLOW_MEMMOVE = true };
+
+ private:
+ const DDLogObject mValue;
+ };
+
+ // Array of all DDLifetimes for a given DDLogObject; they should be
+ // distinguished by their construction&destruction times.
+ using LifetimesForObject = nsTArray<DDLifetime>;
+
+ // For each DDLogObject, we store an array of all objects that have used this
+ // pointer and type.
+ nsClassHashtable<DDLogObjectHashKey, LifetimesForObject> mLifetimes;
+};
+
+} // namespace mozilla
+
+#endif // DDLifetimes_h_