Use shared_ptr to track the runner_context refcount.
Signed-off-by: Martin Wilck <[email protected]>
---
libmpathutil/runner.c | 30 +++++++++---------------------
1 file changed, 9 insertions(+), 21 deletions(-)
diff --git a/libmpathutil/runner.c b/libmpathutil/runner.c
index 8c6d6b9..56abd03 100644
--- a/libmpathutil/runner.c
+++ b/libmpathutil/runner.c
@@ -30,7 +30,6 @@ const char *runner_state_name(int state)
}
struct runner_context {
- int refcount;
int status;
struct timespec deadline;
pthread_t thr;
@@ -39,17 +38,6 @@ struct runner_context {
char __attribute__((aligned(sizeof(void *)))) data[];
};
-static void release_context(struct runner_context *rctx)
-{
- int n;
-
- n = uatomic_sub_return(&rctx->refcount, 1);
- assert(n >= 0);
-
- if (n == 0)
- free(rctx);
-}
-
static void cleanup_context(struct runner_context **prctx)
{
struct runner_context *rctx = *prctx;
@@ -65,7 +53,7 @@ static void cleanup_context(struct runner_context **prctx)
"%s: runner %p finished in state '%s'", __func__, rctx,
runner_state_name(st));
}
- release_context(rctx);
+ put_shared_ptr(rctx);
}
static void *runner_thread(void *arg)
@@ -147,7 +135,7 @@ repeat:
void release_runner(struct runner_context *rctx)
{
cancel_runner(rctx);
- release_context(rctx);
+ put_shared_ptr(rctx);
}
int check_runner(struct runner_context *rctx, void *data, unsigned int size)
@@ -195,17 +183,17 @@ struct runner_context *get_runner(runner_func func, void
*data,
return NULL;
}
- rctx = malloc(sizeof(*rctx) + size);
+ rctx = alloc_shared_ptr(sizeof(*rctx) + size, NULL);
if (!rctx)
return NULL;
rctx->func = func;
/*
- * We have to set the refcount to 2 here. The runner thread may be
- * cancelled before it even had the chance to increase the refcount,
- * which could result in a use-after-free in cleanup_context().
+ * Take an additional reference here. The runner thread may be
+ * cancelled before it even had the chance to take a reference, which
+ * could result in a use-after-free in cleanup_context().
*/
- uatomic_set(&rctx->refcount, 2);
+ get_shared_ptr(rctx);
uatomic_set(&rctx->status, RUNNER_IDLE);
memcpy(rctx->data, data, size);
@@ -222,8 +210,8 @@ struct runner_context *get_runner(runner_func func, void
*data,
if (rc) {
condlog(1, "%s: pthread_create(): %s", __func__, strerror(rc));
- uatomic_dec(&rctx->refcount);
- release_context(rctx);
+ put_shared_ptr(rctx);
+ put_shared_ptr(rctx);
return NULL;
}
return rctx;
--
2.54.0