FileSystemHelpers.h (4144B)
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 DOM_FS_SHARED_FILESYSTEMHELPERS_H_ 8 #define DOM_FS_SHARED_FILESYSTEMHELPERS_H_ 9 10 #include "FileSystemTypes.h" 11 #include "mozilla/RefPtr.h" 12 13 namespace mozilla::dom::fs { 14 15 // XXX Consider moving this class template to MFBT. 16 17 // A wrapper class template on top of the RefPtr. The RefPtr provides us the 18 // automatic reference counting of objects with AddRef() and Release() methods. 19 // `Registered` provides automatic registration counting of objects with 20 // Register() and Unregister() methods. Registration counting works similarly 21 // as reference counting, but objects are not deleted when the number of 22 // registrations drops to zero (that's managed by reference counting). Instead, 23 // an object can trigger an asynchronous close operation which still needs to 24 // hold and use the referenced object. Example: 25 // 26 // using BoolPromise = MozPromise<bool, nsresult, false>; 27 // 28 // class MyObject { 29 // public: 30 // NS_INLINE_DECL_REFCOUNTING(MyObject) 31 // 32 // void Register() { 33 // mRegCnt++; 34 // } 35 // 36 // void Unregister() { 37 // mRegCnt--; 38 // if (mRegCnt == 0) { 39 // BeginClose(); 40 // } 41 // } 42 // 43 // private: 44 // RefPtr<BoolPromise> BeginClose() { 45 // return InvokeAsync(mIOTaskQueue, __func__, 46 // []() { 47 // return BoolPromise::CreateAndResolve(true, __func__); 48 // }) 49 // ->Then(GetCurrentSerialEventTarget(), __func__, 50 // [self = RefPtr<MyObject>(this)]( 51 // const BoolPromise::ResolveOrRejectValue&) { 52 // return self->mIOTaskQueue->BeginShutdown(); 53 // }) 54 // ->Then(GetCurrentSerialEventTarget(), __func__, 55 // [self = RefPtr<MyObject>(this)]( 56 // const ShutdownPromise::ResolveOrRejectValue&) { 57 // return BoolPromise::CreateAndResolve(true, __func__); 58 // }); 59 // } 60 // 61 // RefPtr<TaskQueue> mIOTaskQueue; 62 // uint32_t mRegCnt = 0; 63 // }; 64 65 template <class T> 66 class Registered { 67 private: 68 RefPtr<T> mObject; 69 70 public: 71 ~Registered() { 72 if (mObject) { 73 mObject->Unregister(); 74 } 75 } 76 77 Registered() = default; 78 79 Registered(const Registered& aOther) : mObject(aOther.mObject) { 80 mObject->Register(); 81 } 82 83 Registered(Registered&& aOther) noexcept = default; 84 85 MOZ_IMPLICIT Registered(RefPtr<T> aObject) : mObject(std::move(aObject)) { 86 if (mObject) { 87 mObject->Register(); 88 } 89 } 90 91 Registered<T>& operator=(decltype(nullptr)) { 92 RefPtr<T> oldObject = std::move(mObject); 93 mObject = nullptr; 94 if (oldObject) { 95 oldObject->Unregister(); 96 } 97 return *this; 98 } 99 100 Registered<T>& operator=(const Registered<T>& aRhs) { 101 if (aRhs.mObject) { 102 aRhs.mObject->Register(); 103 } 104 RefPtr<T> oldObject = std::move(mObject); 105 mObject = aRhs.mObject; 106 if (oldObject) { 107 oldObject->Unregister(); 108 } 109 return *this; 110 } 111 112 Registered<T>& operator=(Registered<T>&& aRhs) noexcept { 113 RefPtr<T> oldObject = std::move(mObject); 114 mObject = std::move(aRhs.mObject); 115 aRhs.mObject = nullptr; 116 if (oldObject) { 117 oldObject->Unregister(); 118 } 119 return *this; 120 } 121 122 const RefPtr<T>& inspect() const { return mObject; } 123 124 RefPtr<T> unwrap() { 125 RefPtr<T> oldObject = std::move(mObject); 126 mObject = nullptr; 127 if (oldObject) { 128 oldObject->Unregister(); 129 } 130 return oldObject; 131 } 132 133 T* get() const { return mObject; } 134 135 operator T*() const& { return get(); } 136 137 T* operator->() const { return get(); } 138 }; 139 140 // Spec says valid names don't include (os-dependent) path separators, 141 // and is not equal to a dot . or two dots .. 142 // We want to use the same validator from both child and parent. 143 bool IsValidName(const fs::Name& aName); 144 145 } // namespace mozilla::dom::fs 146 147 #endif // DOM_FS_SHARED_FILESYSTEMHELPERS_H_