From 5690dd5b9ca314806fec6b4581cff2ce1bd70130 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 23 Feb 2026 18:34:12 +0000 Subject: [PATCH] kernel: add support for recursive object destruction (without recursion) this system makes it possible for an object that forms part of a tree to be safely recursively destroyed without using recursion. --- include/kernel/object.h | 5 ++++- kernel/object.c | 25 ++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/include/kernel/object.h b/include/kernel/object.h index 6271e4b..686ab2e 100644 --- a/include/kernel/object.h +++ b/include/kernel/object.h @@ -52,7 +52,10 @@ enum object_type_flags { }; struct object_ops { - kern_status_t (*destroy)(struct object *obj); + kern_status_t (*destroy)(struct object *obj, struct queue *q); + kern_status_t (*destroy_recurse)( + struct queue_entry *entry, + struct object **out); }; struct object_type { diff --git a/kernel/object.c b/kernel/object.c index cf9df21..b4fea5c 100644 --- a/kernel/object.c +++ b/kernel/object.c @@ -83,6 +83,15 @@ struct object *object_ref(struct object *obj) return obj; } +static void __cleanup(struct object *obj, struct queue *queue) +{ + if (HAS_OP(obj, destroy)) { + obj->ob_type->ob_ops.destroy(obj, queue); + } + + vm_cache_free(&obj->ob_type->ob_cache, obj); +} + static void object_cleanup(struct object *obj, unsigned long flags) { if (obj->ob_refcount > 0 || obj->ob_handles > 0) { @@ -90,11 +99,21 @@ static void object_cleanup(struct object *obj, unsigned long flags) return; } - if (HAS_OP(obj, destroy)) { - obj->ob_type->ob_ops.destroy(obj); + struct queue queue = QUEUE_INIT; + __cleanup(obj, &queue); + + if (!HAS_OP(obj, destroy_recurse)) { + return; } - vm_cache_free(&obj->ob_type->ob_cache, obj); + while (!queue_empty(&queue)) { + struct queue_entry *entry = queue_pop_front(&queue); + struct object *child = NULL; + obj->ob_type->ob_ops.destroy_recurse(entry, &child); + if (child) { + __cleanup(child, &queue); + } + } } void object_unref(struct object *obj)