]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bus-wait-for-units: check for existing unit first, use hashmap_ensure_put
authorMike Yuan <me@yhndnzj.com>
Tue, 16 Apr 2024 12:02:33 +0000 (20:02 +0800)
committerMike Yuan <me@yhndnzj.com>
Fri, 19 Apr 2024 02:08:36 +0000 (10:08 +0800)
src/shared/bus-wait-for-units.c
src/shared/bus-wait-for-units.h

index 3a4e8937d336c86e0347434930c5640c26d52ec7..1cb1eb70a6044b93c1934b8fbd608f038b0e5338 100644 (file)
@@ -302,16 +302,19 @@ int bus_wait_for_units_add_unit(
                 void *userdata) {
 
         _cleanup_(wait_for_item_freep) WaitForItem *item = NULL;
+        _cleanup_free_ char *bus_path = NULL;
         int r;
 
         assert(d);
         assert(unit);
+        assert((flags & _BUS_WAIT_FOR_TARGET) != 0);
 
-        assert(flags != 0);
+        bus_path = unit_dbus_path_from_name(unit);
+        if (!bus_path)
+                return -ENOMEM;
 
-        r = hashmap_ensure_allocated(&d->items, &string_hash_ops);
-        if (r < 0)
-                return r;
+        if (hashmap_contains(d->items, bus_path))
+                return 0;
 
         item = new(WaitForItem, 1);
         if (!item)
@@ -319,15 +322,12 @@ int bus_wait_for_units_add_unit(
 
         *item = (WaitForItem) {
                 .flags = flags,
-                .bus_path = unit_dbus_path_from_name(unit),
+                .bus_path = TAKE_PTR(bus_path),
                 .unit_callback = callback,
                 .userdata = userdata,
                 .job_id = UINT32_MAX,
         };
 
-        if (!item->bus_path)
-                return -ENOMEM;
-
         if (!FLAGS_SET(item->flags, BUS_WAIT_REFFED)) {
                 r = sd_bus_call_method_async(
                                 d->bus,
@@ -371,14 +371,16 @@ int bus_wait_for_units_add_unit(
         if (r < 0)
                 return log_debug_errno(r, "Failed to request properties of unit %s: %m", unit);
 
-        r = hashmap_put(d->items, item->bus_path, item);
+        r = hashmap_ensure_put(&d->items, &string_hash_ops, item->bus_path, item);
         if (r < 0)
                 return r;
+        assert(r > 0);
 
         d->state = BUS_WAIT_RUNNING;
         item->parent = d;
         TAKE_PTR(item);
-        return 0;
+
+        return 1;
 }
 
 int bus_wait_for_units_run(BusWaitForUnits *d) {
index 02018e3ec1b4387ba1a5ec8a20f315868e6f643b..09c4f18906c3ec436d5977489b8b45db01cc848c 100644 (file)
@@ -19,6 +19,7 @@ typedef enum BusWaitForUnitsFlags {
         BUS_WAIT_FOR_INACTIVE        = 1 << 1, /* Wait until the unit is back in inactive or dead state */
         BUS_WAIT_NO_JOB              = 1 << 2, /* Wait until there's no more job pending */
         BUS_WAIT_REFFED              = 1 << 3, /* The unit is already reffed with RefUnit() */
+        _BUS_WAIT_FOR_TARGET         = BUS_WAIT_FOR_MAINTENANCE_END|BUS_WAIT_FOR_INACTIVE|BUS_WAIT_NO_JOB,
 } BusWaitForUnitsFlags;
 
 typedef void (*bus_wait_for_units_unit_callback_t)(BusWaitForUnits *d, const char *unit_path, bool good, void *userdata);