From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- dom/fs/shared/FileSystemHelpers.h | 147 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 dom/fs/shared/FileSystemHelpers.h (limited to 'dom/fs/shared/FileSystemHelpers.h') diff --git a/dom/fs/shared/FileSystemHelpers.h b/dom/fs/shared/FileSystemHelpers.h new file mode 100644 index 0000000000..26a820f343 --- /dev/null +++ b/dom/fs/shared/FileSystemHelpers.h @@ -0,0 +1,147 @@ +/* -*- 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 DOM_FS_SHARED_FILESYSTEMHELPERS_H_ +#define DOM_FS_SHARED_FILESYSTEMHELPERS_H_ + +#include "FileSystemTypes.h" +#include "mozilla/RefPtr.h" + +namespace mozilla::dom::fs { + +// XXX Consider moving this class template to MFBT. + +// A wrapper class template on top of the RefPtr. The RefPtr provides us the +// automatic reference counting of objects with AddRef() and Release() methods. +// `Registered` provides automatic registration counting of objects with +// Register() and Unregister() methods. Registration counting works similarly +// as reference counting, but objects are not deleted when the number of +// registrations drops to zero (that's managed by reference counting). Instead, +// an object can trigger an asynchronous close operation which still needs to +// hold and use the referenced object. Example: +// +// using BoolPromise = MozPromise; +// +// class MyObject { +// public: +// NS_INLINE_DECL_REFCOUNTING(MyObject) +// +// void Register() { +// mRegCnt++; +// } +// +// void Unregister() { +// mRegCnt--; +// if (mRegCnt == 0) { +// BeginClose(); +// } +// } +// +// private: +// RefPtr BeginClose() { +// return InvokeAsync(mIOTaskQueue, __func__, +// []() { +// return BoolPromise::CreateAndResolve(true, __func__); +// }) +// ->Then(GetCurrentSerialEventTarget(), __func__, +// [self = RefPtr(this)]( +// const BoolPromise::ResolveOrRejectValue&) { +// return self->mIOTaskQueue->BeginShutdown(); +// }) +// ->Then(GetCurrentSerialEventTarget(), __func__, +// [self = RefPtr(this)]( +// const ShutdownPromise::ResolveOrRejectValue&) { +// return BoolPromise::CreateAndResolve(true, __func__); +// }); +// } +// +// RefPtr mIOTaskQueue; +// uint32_t mRegCnt = 0; +// }; + +template +class Registered { + private: + RefPtr mObject; + + public: + ~Registered() { + if (mObject) { + mObject->Unregister(); + } + } + + Registered() = default; + + Registered(const Registered& aOther) : mObject(aOther.mObject) { + mObject->Register(); + } + + Registered(Registered&& aOther) noexcept = default; + + MOZ_IMPLICIT Registered(RefPtr aObject) : mObject(std::move(aObject)) { + if (mObject) { + mObject->Register(); + } + } + + Registered& operator=(decltype(nullptr)) { + RefPtr oldObject = std::move(mObject); + mObject = nullptr; + if (oldObject) { + oldObject->Unregister(); + } + return *this; + } + + Registered& operator=(const Registered& aRhs) { + if (aRhs.mObject) { + aRhs.mObject->Register(); + } + RefPtr oldObject = std::move(mObject); + mObject = aRhs.mObject; + if (oldObject) { + oldObject->Unregister(); + } + return *this; + } + + Registered& operator=(Registered&& aRhs) noexcept { + RefPtr oldObject = std::move(mObject); + mObject = std::move(aRhs.mObject); + aRhs.mObject = nullptr; + if (oldObject) { + oldObject->Unregister(); + } + return *this; + } + + const RefPtr& inspect() const { return mObject; } + + RefPtr unwrap() { + RefPtr oldObject = std::move(mObject); + mObject = nullptr; + if (oldObject) { + oldObject->Unregister(); + } + return oldObject; + } + + T* get() const { return mObject; } + + operator T*() const& { return get(); } + + T* operator->() const { return get(); } +}; + +// Spec says valid names don't include (os-dependent) path separators, +// and is not equal to a dot . or two dots .. +// We want to use the same validator from both child and parent. +bool IsValidName(const fs::Name& aName); + +} // namespace mozilla::dom::fs + +#endif // DOM_FS_SHARED_FILESYSTEMHELPERS_H_ -- cgit v1.2.3