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);
> +     }
> +}


Reply via email to