8d419f
From 6fcc3befd0ca9897071af071287e8758a30046f0 Mon Sep 17 00:00:00 2001
8d419f
From: Yu Watanabe <watanabe.yu+github@gmail.com>
8d419f
Date: Sun, 17 Apr 2022 07:20:16 +0900
8d419f
Subject: [PATCH] sd-bus: introduce ref/unref function for track_item
8d419f
8d419f
(cherry picked from commit c2d7dd35d2a8cda439384a385b0c1bec804b9b79)
8d419f
8d419f
Related: #2087652
8d419f
---
8d419f
 src/libsystemd/sd-bus/bus-track.c | 35 ++++++++++++++-----------------
8d419f
 1 file changed, 16 insertions(+), 19 deletions(-)
8d419f
8d419f
diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c
8d419f
index 891fd0c899..135dfddc5f 100644
8d419f
--- a/src/libsystemd/sd-bus/bus-track.c
8d419f
+++ b/src/libsystemd/sd-bus/bus-track.c
8d419f
@@ -40,7 +40,6 @@ struct sd_bus_track {
8d419f
                  "arg0='", name, "'")
8d419f
 
8d419f
 static struct track_item* track_item_free(struct track_item *i) {
8d419f
-
8d419f
         if (!i)
8d419f
                 return NULL;
8d419f
 
8d419f
@@ -49,7 +48,8 @@ static struct track_item* track_item_free(struct track_item *i) {
8d419f
         return mfree(i);
8d419f
 }
8d419f
 
8d419f
-DEFINE_TRIVIAL_CLEANUP_FUNC(struct track_item*, track_item_free);
8d419f
+DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(struct track_item, track_item, track_item_free);
8d419f
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct track_item*, track_item_unref);
8d419f
 DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(track_item_hash_ops, char, string_hash_func, string_compare_func,
8d419f
                                               struct track_item, track_item_free);
8d419f
 
8d419f
@@ -180,7 +180,7 @@ static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus
8d419f
 }
8d419f
 
8d419f
 _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
8d419f
-        _cleanup_(track_item_freep) struct track_item *n = NULL;
8d419f
+        _cleanup_(track_item_unrefp) struct track_item *n = NULL;
8d419f
         struct track_item *i;
8d419f
         const char *match;
8d419f
         int r;
8d419f
@@ -190,14 +190,8 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
8d419f
 
8d419f
         i = hashmap_get(track->names, name);
8d419f
         if (i) {
8d419f
-                if (track->recursive) {
8d419f
-                        unsigned k = i->n_ref + 1;
8d419f
-
8d419f
-                        if (k < i->n_ref) /* Check for overflow */
8d419f
-                                return -EOVERFLOW;
8d419f
-
8d419f
-                        i->n_ref = k;
8d419f
-                }
8d419f
+                if (track->recursive)
8d419f
+                        track_item_ref(i);
8d419f
 
8d419f
                 bus_track_remove_from_queue(track);
8d419f
                 return 0;
8d419f
@@ -207,9 +201,14 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
8d419f
         if (r < 0)
8d419f
                 return r;
8d419f
 
8d419f
-        n = new0(struct track_item, 1);
8d419f
+        n = new(struct track_item, 1);
8d419f
         if (!n)
8d419f
                 return -ENOMEM;
8d419f
+
8d419f
+        *n = (struct track_item) {
8d419f
+                .n_ref = 1,
8d419f
+        };
8d419f
+
8d419f
         n->name = strdup(name);
8d419f
         if (!n->name)
8d419f
                 return -ENOMEM;
8d419f
@@ -241,8 +240,7 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) {
8d419f
                 return r;
8d419f
         }
8d419f
 
8d419f
-        n->n_ref = 1;
8d419f
-        n = NULL;
8d419f
+        TAKE_PTR(n);
8d419f
 
8d419f
         bus_track_remove_from_queue(track);
8d419f
         track->modified = true;
8d419f
@@ -264,14 +262,13 @@ _public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) {
8d419f
         i = hashmap_get(track->names, name);
8d419f
         if (!i)
8d419f
                 return -EUNATCH;
8d419f
-        if (i->n_ref <= 0)
8d419f
-                return -EUNATCH;
8d419f
 
8d419f
-        i->n_ref--;
8d419f
-
8d419f
-        if (i->n_ref <= 0)
8d419f
+        assert(i->n_ref >= 1);
8d419f
+        if (i->n_ref <= 1)
8d419f
                 return bus_track_remove_name_fully(track, name);
8d419f
 
8d419f
+        track_item_unref(i);
8d419f
+
8d419f
         return 1;
8d419f
 }
8d419f