Utilize the share_ptr code for tracking the refcount of checker classes.

Signed-off-by: Martin Wilck <[email protected]>
---
 libmultipath/checkers.c | 98 +++++++++--------------------------------
 libmultipath/checkers.h |  2 -
 2 files changed, 20 insertions(+), 80 deletions(-)

diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
index 8f18ca6..a3b9cc8 100644
--- a/libmultipath/checkers.c
+++ b/libmultipath/checkers.c
@@ -39,41 +39,11 @@ const char *checker_state_name(int i)
        return checker_state_names[i];
 }
 
-static struct checker_class *alloc_checker_class(void)
+static void free_checker_class(void *ptr)
 {
-       struct checker_class *c;
-
-       c = calloc(1, sizeof(struct checker_class));
-       if (c) {
-               INIT_LIST_HEAD(&c->node);
-               uatomic_set(&c->refcount, 1);
-       }
-       return c;
-}
-
-/* Use uatomic_{sub,add}_return() to ensure proper memory barriers */
-static int checker_class_ref(struct checker_class *cls)
-{
-       return uatomic_add_return(&cls->refcount, 1);
-}
-
-static int checker_class_unref(struct checker_class *cls)
-{
-       return uatomic_sub_return(&cls->refcount, 1);
-}
-
-void free_checker_class(struct checker_class *c)
-{
-       int cnt;
-
+       struct checker_class *c = ptr;
        if (!c)
                return;
-       cnt = checker_class_unref(c);
-       if (cnt != 0) {
-               condlog(cnt < 0 ? 1 : 4, "%s checker refcount %d",
-                       c->name, cnt);
-               return;
-       }
        condlog(3, "unloading %s checker", c->name);
        list_del(&c->node);
        if (c->reset)
@@ -84,7 +54,18 @@ void free_checker_class(struct checker_class *c)
                                c->name, dlerror());
                }
        }
-       free(c);
+}
+
+static struct checker_class *alloc_checker_class(void)
+{
+       struct checker_class *c;
+
+       c = alloc_shared_ptr(sizeof(*c), free_checker_class);
+       if (c) {
+               memset(c, 0, sizeof(*c));
+               INIT_LIST_HEAD(&c->node);
+       }
+       return c;
 }
 
 void cleanup_checkers (void)
@@ -92,9 +73,8 @@ void cleanup_checkers (void)
        struct checker_class *checker_loop;
        struct checker_class *checker_temp;
 
-       list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node) {
-               free_checker_class(checker_loop);
-       }
+       list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node)
+               put_shared_ptr(checker_loop);
 }
 
 static struct checker_class *checker_class_lookup(const char *name)
@@ -163,8 +143,7 @@ static struct checker_class *add_checker_class(const char 
*name)
                goto out;
 
        c->mp_init = (int (*)(struct checker *)) dlsym(c->handle, 
"libcheck_mp_init");
-       c->reset = (void (*)(void)) dlsym(c->handle, "libcheck_reset");
-       c->thread = (void *(*)(void*)) dlsym(c->handle, "libcheck_thread");
+       c->reset = (void (*)(void))dlsym(c->handle, "libcheck_reset");
        c->pending = (int (*)(struct checker *)) dlsym(c->handle, 
"libcheck_pending");
        c->need_wait = (bool (*)(struct checker *)) dlsym(c->handle, 
"libcheck_need_wait");
        /* These 5 functions can be NULL. call dlerror() to clear out any
@@ -199,7 +178,7 @@ done:
        list_add(&c->node, &checkers);
        return c;
 out:
-       free_checker_class(c);
+       put_shared_ptr(c);
        return NULL;
 }
 
@@ -285,7 +264,7 @@ void checker_put (struct checker * dst)
        if (src && src->free)
                src->free(dst);
        checker_clear(dst);
-       free_checker_class(src);
+       put_shared_ptr(src);
 }
 
 int checker_get_state(struct checker *c)
@@ -371,43 +350,6 @@ bad_id:
        return generic_msg[CHECKER_MSGID_NONE];
 }
 
-static void checker_cleanup_thread(void *arg)
-{
-       struct checker_class *cls = arg;
-
-       free_checker_class(cls);
-       rcu_unregister_thread();
-}
-
-static void *checker_thread_entry(void *arg)
-{
-       struct checker_context *ctx = arg;
-       void *rv;
-
-       rcu_register_thread();
-       pthread_cleanup_push(checker_cleanup_thread, ctx->cls);
-       rv = ctx->cls->thread(ctx);
-       pthread_cleanup_pop(1);
-       return rv;
-}
-
-int start_checker_thread(pthread_t *thread, const pthread_attr_t *attr,
-                        struct checker_context *ctx)
-{
-       int rv;
-
-       assert(ctx && ctx->cls && ctx->cls->thread);
-       /* Take a ref here, lest the class be freed before the thread starts */
-       (void)checker_class_ref(ctx->cls);
-       rv = pthread_create(thread, attr, checker_thread_entry, ctx);
-       if (rv != 0) {
-               condlog(1, "failed to start checker thread for %s: %m",
-                       ctx->cls->name);
-               checker_class_unref(ctx->cls);
-       }
-       return rv;
-}
-
 void checker_clear_message (struct checker *c)
 {
        if (!c)
@@ -431,7 +373,7 @@ void checker_get(struct checker *dst, const char *name)
        if (!src)
                return;
 
-       (void)checker_class_ref(dst->cls);
+       get_shared_ptr(dst->cls);
 }
 
 int init_checkers(void)
diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
index 694dfa3..630e987 100644
--- a/libmultipath/checkers.h
+++ b/libmultipath/checkers.h
@@ -135,7 +135,6 @@ struct checker;
 struct checker_class {
        struct list_head node;
        void *handle;
-       int refcount;
        int sync;
        char name[CHECKER_NAME_LEN];
        int (*check)(struct checker *);
@@ -143,7 +142,6 @@ struct checker_class {
        int (*mp_init)(struct checker *); /* to allocate the mpcontext */
        void (*free)(struct checker *);   /* to free the context */
        void (*reset)(void);              /* to reset the global variables */
-       void *(*thread)(void *);          /* async thread entry point */
        int (*pending)(struct checker *); /* to recheck pending paths */
        bool (*need_wait)(struct checker *); /* checker needs waiting for */
        const char **msgtable;
-- 
2.54.0


Reply via email to