Re: [PATCH v2 04/19] libmpathutil: add implementation of generic shared pointer
Benjamin Marzinski <[email protected]>
| Newsgroups | dev.linux.lists.dm-devel |
|---|---|
| Message-ID | <[email protected]> |
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); > + } > +}