Add a set of simple functions to handle refcounted pointers.
Signed-off-by: Martin Wilck <[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/libmpathutil.version
b/libmpathutil/libmpathutil.version
index c69120d..51594ad 100644
--- a/libmpathutil/libmpathutil.version
+++ b/libmpathutil/libmpathutil.version
@@ -194,3 +194,10 @@ global:
local:
*;
};
+
+LIBMPATHUTIL_6.1 {
+global:
+ alloc_shared_ptr;
+ get_shared_ptr;
+ put_shared_ptr;
+} LIBMPATHUTIL_6.0;
diff --git a/libmpathutil/util.c b/libmpathutil/util.c
index 23a9797..3c623ec 100644
--- a/libmpathutil/util.c
+++ b/libmpathutil/util.c
@@ -12,15 +12,13 @@
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
+#include <urcu/uatomic.h>
#include "mt-udev-wrap.h"
#include "util.h"
#include "debug.h"
-#include "checkers.h"
#include "vector.h"
-#include "structs.h"
-#include "config.h"
-#include "log.h"
+#include "list.h"
size_t
strchop(char *str)
@@ -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)
+{
+ 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);
+ }
+}
diff --git a/libmpathutil/util.h b/libmpathutil/util.h
index aed1bc1..ffbb182 100644
--- a/libmpathutil/util.h
+++ b/libmpathutil/util.h
@@ -160,4 +160,9 @@ void cleanup_charp(char **p);
void cleanup_ucharp(unsigned char **p);
void cleanup_udev_device(struct udev_device **udd);
void cleanup_bitfield(union bitfield **p);
+
+void *alloc_shared_ptr(size_t size, void (*destructor)(void *));
+void get_shared_ptr(void *ptr);
+void put_shared_ptr(void *ptr);
+
#endif /* UTIL_H_INCLUDED */
--
2.54.0