On Fri, May 22, 2026 at 06:44:00PM +0200, Martin Wilck wrote:
> Add a set of simple functions to handle refcounted pointers.
>
> Signed-off-by: Martin Wilck <[email protected]>
> Reviewed-by: Benjamin Marzinski <[email protected]>
> ---
> libmpathutil/libmpathutil.version | 7 +++++
> libmpathutil/util.c | 45 ++++++++++++++++++++++++++++---
> libmpathutil/util.h | 5 ++++
> 3 files changed, 53 insertions(+), 4 deletions(-)
>
> diff --git a/libmpathutil/util.c b/libmpathutil/util.c
> index 23a9797..3c623ec 100644
> --- a/libmpathutil/util.c
> +++ b/libmpathutil/util.c
> @@ -384,3 +382,42 @@ void cleanup_udev_device(struct udev_device **udd)
> if (*udd)
> udev_device_unref(*udd);
> }
> +
> +struct shared_ptr {
> + long refcnt;
> + void (*destructor)(void *);
> + char __attribute__((aligned(sizeof(void *)))) ptr[];
> +};
> +
> +void *alloc_shared_ptr(size_t size, void (*destructor)(void *))
> +{
> + struct shared_ptr *sp = malloc(sizeof(*sp) + size);
> +
> + if (!sp)
> + return NULL;
> + uatomic_set(&sp->refcnt, 1);
> + sp->destructor = destructor;
> + return sp->ptr;
> +}
> +
> +void get_shared_ptr(void *ptr)
> +{
We should probably return here if ptr is NULL, like we do in
put_shared_ptr(). Alternatively, this might be a reasonable place for an
assert(), since nobody should be calling these with NULL pointers.
As far as the general question Hannes raise about this implentantion,
I'm happy with it as-is.
-Ben
> + struct shared_ptr *sp = container_of(ptr, struct shared_ptr, ptr);
> +
> + if (uatomic_add_return(&sp->refcnt, 1) < 0)
> + condlog(0, "%s: refcount overflow", __func__);
> +}
> +
> +void put_shared_ptr(void *ptr)
> +{
> + struct shared_ptr *sp;
> +
> + if (!ptr)
> + return;
> + sp = container_of(ptr, struct shared_ptr, ptr);
> + if (uatomic_sub_return(&sp->refcnt, 1) == 0) {
> + if (sp->destructor)
> + sp->destructor(ptr);
> + free(sp);
> + }
> +}