diff options
Diffstat (limited to '')
| -rw-r--r-- | include/LifecycleManager.h | 75 |
1 files changed, 69 insertions, 6 deletions
diff --git a/include/LifecycleManager.h b/include/LifecycleManager.h index 8126820..5508bc6 100644 --- a/include/LifecycleManager.h +++ b/include/LifecycleManager.h @@ -1,6 +1,7 @@ #pragma once #include "Api.h" +#include "IStorageBackend.h" #include "ObjectManager.h" /** @@ -15,9 +16,9 @@ namespace nt * * Object lifetime is governed by two independent counters in registry_head: * `handle_count` (sessions holding an open handle) and `reference_count` - * (structural dependencies such as cursors pinned to a snapshot or views - * referencing base relations). An object is eligible for GC only when both - * reach zero. + * (structural dependencies such as cursors pinned to a snapshot or + * ephemeral relations referencing their base relations). An object is + * eligible for GC only when both reach zero. * * Monitor / Unmonitor manage `handle_count`. Pin / Unpin manage * `reference_count`. See docs/reactos-ob-comparison.md §1. @@ -26,6 +27,18 @@ namespace nt { public: /** + * @brief Constructs a LifecycleManager bound to a registry and store. + * + * Needs the registry to perform GC: Unmonitor and Unpin call + * ObjectManager::Unregister once both counters reach zero. Type-specific + * cleanup (e.g. cascading a Multigroup's pin to its child Relations, + * or a BranchTree's pin to its child Multigroups) runs inside the + * lifecycle manager before the entry is spliced out. The storage + * backend is needed by CascadeBranchTree to page the merkle nodes. + */ + LifecycleManager(ObjectManager& objects, IStorageBackend& storage); + + /** * @brief Starts monitoring an object's lifecycle. * * Increments `handle_count` on the object's registry_head. Should be @@ -53,9 +66,9 @@ namespace nt * @brief Increments the structural dependency count on an object. * * Call when one object takes a dependency on another — for example when - * a cursor pins an immutable snapshot version, or when a view is - * registered against its base relations. Prevents GC of the target object - * while the dependency is live. + * a cursor pins an immutable snapshot version, or when an ephemeral + * relation is registered against its base relations. Prevents GC of the + * target object while the dependency is live. * * @todo Implement. See docs/reactos-ob-comparison.md §1. * @@ -76,6 +89,15 @@ namespace nt void Unpin(ObjectManager::registry* object); /** + * @brief Returns true when the object is GC-eligible right now. + * + * Eligibility is the joint condition handle_count == 0 && + * reference_count == 0. Decrement callers (Unmonitor / Unpin) consult + * this and, when true, run type-specific cleanup before unregistering. + */ + bool IsEligibleForGC(ObjectManager::registry* object) const; + + /** * @brief Serializes contention for changes to mutable reference states. * * Immutable objects — relation snapshots, multigroup snapshots, @@ -97,5 +119,46 @@ namespace nt * @return True when the operation may proceed. */ const bool Contention(ObjectManager::registry* object); + + private: + /** + * @brief Joint-counters check + type-specific cascade + Unregister. + * + * Called by Unmonitor and Unpin after their decrement. No-op when the + * object is still referenced. When eligible: + * - MULTIGROUP entries first unpin every Relation registered as a + * direct child of their /system/snapshots/H subtree. + * - BRANCH_TREE entries first unpin every Multigroup their + * content-addressed tree references. + * - The entry is then removed from the registry; its IObject and + * registry_head are freed. + * + * Inline GC for now; the reaper-queue deferred-deletion pattern from + * docs/reactos-ob-comparison.md §7 is a later optimisation. + */ + void TryCollect(ObjectManager::registry* object); + + /** + * @brief Releases pins held by a MULTIGROUP entry on its child Relations. + * + * Iterates the registry once, collects every /system/snapshots/<H>/<n> + * direct child, and calls Unpin on each. Triggered exclusively from + * TryCollect at the moment the parent snapshot becomes eligible for GC. + */ + void CascadeMultigroup(ObjectManager::registry* multigroup); + + /** + * @brief Releases pins held by a BRANCH_TREE entry on its child mgs. + * + * Pages the Merkle<std::string> tree at the BranchTree's merkle_root, + * resolves each (mg_name, mg_hash) entry to its + * /system/snapshots/<mg_hash> Multigroup, and calls Unpin on it. + * Triggered exclusively from TryCollect at the moment the BranchTree + * itself becomes eligible for GC. + */ + void CascadeBranchTree(ObjectManager::registry* branch_tree); + + ObjectManager& objects_; + IStorageBackend& storage_; }; } |
