From 8259c2e7064e5d03759de4a934fbb595949dae63 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 26 Jul 2019 08:50:29 +1000 Subject: [PATCH] ratbagd: introduce ref/unref for ratbagd_device pointers We'll need to keep references around to devices even when caller is done with them. Signed-off-by: Peter Hutterer --- ratbagd/ratbagd-device.c | 30 ++++++++++++++++++++++++++---- ratbagd/ratbagd-test.c | 2 +- ratbagd/ratbagd.c | 4 ++-- ratbagd/ratbagd.h | 5 +++-- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ratbagd/ratbagd-device.c b/ratbagd/ratbagd-device.c index c8ef74eb..bc8d0cad 100644 --- a/ratbagd/ratbagd-device.c +++ b/ratbagd/ratbagd-device.c @@ -41,6 +41,8 @@ #include "libratbag-util.h" struct ratbagd_device { + unsigned int refcount; + struct ratbagd *ctx; RBNode node; char *sysname; @@ -230,7 +232,7 @@ int ratbagd_device_new(struct ratbagd_device **out, const char *sysname, struct ratbag_device *lib_device) { - _cleanup_(ratbagd_device_freep) struct ratbagd_device *device = NULL; + _cleanup_(ratbagd_device_unrefp) struct ratbagd_device *device = NULL; struct ratbag_profile *profile; unsigned int i; int r; @@ -240,6 +242,7 @@ int ratbagd_device_new(struct ratbagd_device **out, assert(sysname); device = zalloc(sizeof(*device)); + device->refcount = 1; device->ctx = ctx; rbnode_init(&device->node); device->lib_device = ratbag_device_ref(lib_device); @@ -282,12 +285,12 @@ int ratbagd_device_new(struct ratbagd_device **out, return 0; } -struct ratbagd_device *ratbagd_device_free(struct ratbagd_device *device) +static void ratbagd_device_free(struct ratbagd_device *device) { unsigned int i; if (!device) - return NULL; + return; assert(!ratbagd_device_linked(device)); @@ -301,7 +304,26 @@ struct ratbagd_device *ratbagd_device_free(struct ratbagd_device *device) assert(!device->lib_device); /* ratbag yields !NULL if still pinned */ - return mfree(device); + mfree(device); +} + +struct ratbagd_device *ratbagd_device_ref(struct ratbagd_device *device) +{ + assert(device->refcount > 0); + + ++device->refcount; + return device; +} + +struct ratbagd_device *ratbagd_device_unref(struct ratbagd_device *device) +{ + assert(device->refcount > 0); + + --device->refcount; + if (device->refcount == 0) + ratbagd_device_free(device); + + return NULL; } const char *ratbagd_device_get_sysname(struct ratbagd_device *device) diff --git a/ratbagd/ratbagd-test.c b/ratbagd/ratbagd-test.c index fe5a4950..fca90192 100644 --- a/ratbagd/ratbagd-test.c +++ b/ratbagd/ratbagd-test.c @@ -185,7 +185,7 @@ int ratbagd_reset_test_device(sd_bus_message *m, if (ratbagd_test_device) { ratbagd_device_unlink(ratbagd_test_device); - ratbagd_device_free(ratbagd_test_device); + ratbagd_device_unref(ratbagd_test_device); (void) sd_bus_emit_properties_changed(ctx->bus, RATBAGD_OBJ_ROOT, diff --git a/ratbagd/ratbagd.c b/ratbagd/ratbagd.c index 6c462b68..bac37e37 100644 --- a/ratbagd/ratbagd.c +++ b/ratbagd/ratbagd.c @@ -200,7 +200,7 @@ static void ratbagd_process_device(struct ratbagd *ctx, /* device was removed, unlink it and destroy our context */ if (device) { ratbagd_device_unlink(device); - ratbagd_device_free(device); + ratbagd_device_unref(device); (void) sd_bus_emit_properties_changed(ctx->bus, RATBAGD_OBJ_ROOT, @@ -283,7 +283,7 @@ static struct ratbagd *ratbagd_free(struct ratbagd *ctx) RATBAGD_DEVICE_FOREACH_SAFE(device, tmp, ctx) { ratbagd_device_unlink(device); - ratbagd_device_free(device); + ratbagd_device_unref(device); } ctx->bus = sd_bus_flush_close_unref(ctx->bus); diff --git a/ratbagd/ratbagd.h b/ratbagd/ratbagd.h index a3a6b045..a980db54 100644 --- a/ratbagd/ratbagd.h +++ b/ratbagd/ratbagd.h @@ -170,7 +170,8 @@ int ratbagd_device_new(struct ratbagd_device **out, struct ratbagd *ctx, const char *sysname, struct ratbag_device *lib_device); -struct ratbagd_device *ratbagd_device_free(struct ratbagd_device *device); +struct ratbagd_device *ratbagd_device_ref(struct ratbagd_device *device); +struct ratbagd_device *ratbagd_device_unref(struct ratbagd_device *device); const char *ratbagd_device_get_sysname(struct ratbagd_device *device); const char *ratbagd_device_get_path(struct ratbagd_device *device); unsigned int ratbagd_device_get_num_buttons(struct ratbagd_device *device); @@ -181,7 +182,7 @@ bool ratbagd_device_linked(struct ratbagd_device *device); void ratbagd_device_link(struct ratbagd_device *device); void ratbagd_device_unlink(struct ratbagd_device *device); -DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_device *, ratbagd_device_free); +DEFINE_TRIVIAL_CLEANUP_FUNC(struct ratbagd_device *, ratbagd_device_unref); struct ratbagd_device *ratbagd_device_lookup(struct ratbagd *ctx, const char *name);