summaryrefslogtreecommitdiffstats
path: root/dom/ipc/MaybeDiscarded.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/ipc/MaybeDiscarded.h')
-rw-r--r--dom/ipc/MaybeDiscarded.h133
1 files changed, 133 insertions, 0 deletions
diff --git a/dom/ipc/MaybeDiscarded.h b/dom/ipc/MaybeDiscarded.h
new file mode 100644
index 0000000000..32c0dde3b9
--- /dev/null
+++ b/dom/ipc/MaybeDiscarded.h
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 mozilla_dom_MaybeDiscarded_h
+#define mozilla_dom_MaybeDiscarded_h
+
+#include "mozilla/RefPtr.h"
+
+namespace mozilla::dom {
+
+// Wrapper type for a WindowContext or BrowsingContext instance which may be
+// discarded, and thus unavailable in the current process. This type is used to
+// pass WindowContext and BrowsingContext instances over IPC, as they may be
+// discarded in the receiving process.
+//
+// A MaybeDiscarded can generally be implicitly converted to from a
+// BrowsingContext* or WindowContext*, but requires an explicit check of
+// |IsDiscarded| and call to |get| to read from.
+template <typename T>
+class MaybeDiscarded {
+ public:
+ MaybeDiscarded() = default;
+ MaybeDiscarded(MaybeDiscarded<T>&&) = default;
+ MaybeDiscarded(const MaybeDiscarded<T>&) = default;
+
+ // Construct from raw pointers and |nullptr|.
+ MOZ_IMPLICIT MaybeDiscarded(T* aRawPtr)
+ : mId(aRawPtr ? aRawPtr->Id() : 0), mPtr(aRawPtr) {}
+ MOZ_IMPLICIT MaybeDiscarded(decltype(nullptr)) {}
+
+ // Construct from |RefPtr<I>|
+ template <typename I,
+ typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
+ MOZ_IMPLICIT MaybeDiscarded(RefPtr<I>&& aPtr)
+ : mId(aPtr ? aPtr->Id() : 0), mPtr(std::move(aPtr)) {}
+ template <typename I,
+ typename = std::enable_if_t<std::is_convertible_v<I*, T*>>>
+ MOZ_IMPLICIT MaybeDiscarded(const RefPtr<I>& aPtr)
+ : mId(aPtr ? aPtr->Id() : 0), mPtr(aPtr) {}
+
+ // Basic assignment operators.
+ MaybeDiscarded<T>& operator=(const MaybeDiscarded<T>&) = default;
+ MaybeDiscarded<T>& operator=(MaybeDiscarded<T>&&) = default;
+ MaybeDiscarded<T>& operator=(decltype(nullptr)) {
+ mId = 0;
+ mPtr = nullptr;
+ return *this;
+ }
+ MaybeDiscarded<T>& operator=(T* aRawPtr) {
+ mId = aRawPtr ? aRawPtr->Id() : 0;
+ mPtr = aRawPtr;
+ return *this;
+ }
+ template <typename I>
+ MaybeDiscarded<T>& operator=(const RefPtr<I>& aRhs) {
+ mId = aRhs ? aRhs->Id() : 0;
+ mPtr = aRhs;
+ return *this;
+ }
+ template <typename I>
+ MaybeDiscarded<T>& operator=(RefPtr<I>&& aRhs) {
+ mId = aRhs ? aRhs->Id() : 0;
+ mPtr = std::move(aRhs);
+ return *this;
+ }
+
+ // Validate that the value is neither discarded nor null.
+ bool IsNullOrDiscarded() const { return !mPtr || mPtr->IsDiscarded(); }
+ bool IsDiscarded() const { return IsNullOrDiscarded() && !IsNull(); }
+ bool IsNull() const { return mId == 0; }
+
+ explicit operator bool() const { return !IsNullOrDiscarded(); }
+
+ // Extract the wrapped |T|. Must not be called on a discarded |T|.
+ T* get() const {
+ MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
+ return mPtr.get();
+ }
+ already_AddRefed<T> forget() {
+ MOZ_DIAGNOSTIC_ASSERT(!IsDiscarded());
+ return mPtr.forget();
+ }
+
+ T* operator->() const {
+ MOZ_ASSERT(!IsNull());
+ return get();
+ }
+
+ // Like "get", but gets the "Canonical" version of the type. This method may
+ // only be called in the parent process.
+ auto get_canonical() const -> decltype(get()->Canonical()) {
+ if (get()) {
+ return get()->Canonical();
+ } else {
+ return nullptr;
+ }
+ }
+
+ // The ID for the context wrapped by this MaybeDiscarded. This ID comes from a
+ // remote process, and should generally only be used for logging. A
+ // BrowsingContext with this ID may not exist in the current process.
+ uint64_t ContextId() const { return mId; }
+
+ // Tries to get the wrapped value, disregarding discarded status.
+ // This may return |nullptr| for a non-null |MaybeDiscarded|, in the case that
+ // the target is no longer available in this process.
+ T* GetMaybeDiscarded() const { return mPtr.get(); }
+
+ // Clear the value to a discarded state with the given ID.
+ void SetDiscarded(uint64_t aId) {
+ mId = aId;
+ mPtr = nullptr;
+ }
+
+ // Comparison operators required by IPDL
+ bool operator==(const MaybeDiscarded<T>& aRhs) const {
+ return mId == aRhs.mId && mPtr == aRhs.mPtr;
+ }
+ bool operator!=(const MaybeDiscarded<T>& aRhs) const {
+ return !operator==(aRhs);
+ }
+
+ private:
+ uint64_t mId = 0;
+ RefPtr<T> mPtr;
+};
+
+} // namespace mozilla::dom
+
+#endif // mozilla_dom_MaybeDiscarded_h