ClientDirectoryLockHandle.h (4248B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef DOM_QUOTA_CLIENTDIRECTORYLOCKHANDLE_H_ 8 #define DOM_QUOTA_CLIENTDIRECTORYLOCKHANDLE_H_ 9 10 #include "mozilla/RefPtr.h" 11 #include "mozilla/dom/quota/ConditionalCompilation.h" 12 #include "nsISupportsImpl.h" 13 14 namespace mozilla::dom::quota { 15 16 class ClientDirectoryLock; 17 18 /** 19 * @class ClientDirectoryLockHandle 20 * @brief RAII-style wrapper for managing a ClientDirectoryLock. 21 * 22 * ClientDirectoryLockHandle is a RAII-style wrapper that manages a 23 * ClientDirectoryLock created by QuotaManager::OpenClientDirectory. 24 * 25 * This class ensures that the associated directory lock remains acquired 26 * while the handle is in scope and automatically drops it when destroyed. 27 * 28 * ## Usage: 29 * - See QuotaManager::OpenClientDirectory for details on obtaining a 30 * ClientDirectoryLockHandle. 31 * - The handle should be retained for as long as access to the directory is 32 * needed. 33 * 34 * ## Threading: 35 * - Must be used only on the thread that created it, except that it may be 36 * safely destroyed from another thread after being moved (see also 37 * Destruction). 38 * - `AssertIsOnOwningThread()` is primarily used internally to verify correct 39 * threading, but clients can use it for additional thread-safety checks if 40 * needed. 41 * 42 * ## Destruction: 43 * - If the lock has already been dropped (e.g., due to move), the destructor 44 * does nothing. 45 * - The destructor automatically drops the lock if it is still held. 46 * - Thus, it is safe to destroy a handle from any thread as long as the handle 47 * was moved beforehand on the owning thread. 48 * 49 * ## Key Features: 50 * - Move-only: Prevents accidental copies. 51 * - Implicit boolean conversion to check if the handle holds a valid 52 * `ClientDirectoryLock`. 53 * - Easy access to the underlying ClientDirectoryLock using `operator*` and 54 * `operator->`. 55 * - Moved-from handles are placed in a well-defined inert state and can be 56 * safely inspected using `IsInert()` for diagnostic purposes. 57 */ 58 class ClientDirectoryLockHandle final { 59 public: 60 ClientDirectoryLockHandle(); 61 62 explicit ClientDirectoryLockHandle( 63 RefPtr<ClientDirectoryLock> aClientDirectoryLock); 64 65 ClientDirectoryLockHandle(const ClientDirectoryLockHandle&) = delete; 66 67 ClientDirectoryLockHandle(ClientDirectoryLockHandle&& aOther) noexcept; 68 69 ~ClientDirectoryLockHandle(); 70 71 void AssertIsOnOwningThread() const; 72 73 ClientDirectoryLockHandle& operator=(const ClientDirectoryLockHandle&) = 74 delete; 75 76 ClientDirectoryLockHandle& operator=( 77 ClientDirectoryLockHandle&& aOther) noexcept; 78 79 explicit operator bool() const; 80 81 ClientDirectoryLock* get() const; 82 83 ClientDirectoryLock& operator*() const; 84 85 ClientDirectoryLock* operator->() const; 86 87 bool IsRegistered() const; 88 89 void SetRegistered(bool aRegistered); 90 91 /** 92 * Returns true if this handle is in an inert state — either it was 93 * default-constructed and never assigned a lock, or it was explicitly 94 * cleared (via move). 95 * 96 * This method is primarily intended for use in destructors of objects that 97 * own a ClientDirectoryLockHandle, to assert that the lock has been properly 98 * dropped and cleared before destruction. 99 * 100 * It is safe to call this method at any time on the owning thread. It may 101 * also be called from other threads during destruction, under the assumption 102 * that no other thread is concurrently accessing or modifying the handle. 103 * 104 * This method should not be used for control flow or runtime decision 105 * making. 106 */ 107 DIAGNOSTICONLY(bool IsInert() const); 108 109 private: 110 NS_DECL_OWNINGTHREAD 111 112 // If new members are added or existing ones are changed, make sure to update 113 // the move constructor and move assignment operator accordingly to preserve 114 // correct state during moves. 115 RefPtr<ClientDirectoryLock> mClientDirectoryLock; 116 117 bool mRegistered = false; 118 }; 119 120 } // namespace mozilla::dom::quota 121 122 #endif // DOM_QUOTA_CLIENTDIRECTORYLOCKHANDLE_H_