X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-objects.c;h=b116a5dd10146ddc729abade07fd4bf7d11b3c05;hb=9130f2128b64de19a3b7d6db7e0d371adfd296c2;hp=68437f1e37f86ac6de035b30262948fdd079c4cd;hpb=a03e4337fd2ae1cc90989e9b7b5f160b42cdb021;p=elogind.git diff --git a/src/libsystemd-bus/bus-objects.c b/src/libsystemd-bus/bus-objects.c index 68437f1e3..b116a5dd1 100644 --- a/src/libsystemd-bus/bus-objects.c +++ b/src/libsystemd-bus/bus-objects.c @@ -1593,15 +1593,25 @@ static void free_node_vtable(sd_bus *bus, struct node_vtable *w) { free(w); } -static unsigned vtable_member_hash_func(const void *a) { +static unsigned long vtable_member_hash_func(const void *a, const uint8_t hash_key[HASH_KEY_SIZE]) { const struct vtable_member *m = a; + uint8_t hash_key2[HASH_KEY_SIZE]; + unsigned long ret; assert(m); - return - string_hash_func(m->path) ^ - string_hash_func(m->interface) ^ - string_hash_func(m->member); + ret = string_hash_func(m->path, hash_key); + + /* Use a slightly different hash key for the interface */ + memcpy(hash_key2, hash_key, HASH_KEY_SIZE); + hash_key2[0]++; + ret ^= string_hash_func(m->interface, hash_key2); + + /* And an even different one for the member */ + hash_key2[0]++; + ret ^= string_hash_func(m->member, hash_key2); + + return ret; } static int vtable_member_compare_func(const void *a, const void *b) { @@ -1971,6 +1981,7 @@ static int emit_properties_changed_on_interface( const char *path, const char *interface, bool require_fallback, + bool *found_interface, char **names) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; @@ -1987,6 +1998,7 @@ static int emit_properties_changed_on_interface( assert(prefix); assert(path); assert(interface); + assert(found_interface); n = hashmap_get(bus->nodes, prefix); if (!n) @@ -2022,6 +2034,8 @@ static int emit_properties_changed_on_interface( if (r == 0) continue; + *found_interface = true; + if (names) { /* If the caller specified a list of * properties we include exactly those in the @@ -2175,6 +2189,7 @@ _public_ int sd_bus_emit_properties_changed_strv( char **names) { BUS_DONT_DESTROY(bus); + bool found_interface = false; char *prefix; int r; @@ -2195,7 +2210,7 @@ _public_ int sd_bus_emit_properties_changed_strv( do { bus->nodes_modified = false; - r = emit_properties_changed_on_interface(bus, path, path, interface, false, names); + r = emit_properties_changed_on_interface(bus, path, path, interface, false, &found_interface, names); if (r != 0) return r; if (bus->nodes_modified) @@ -2203,7 +2218,7 @@ _public_ int sd_bus_emit_properties_changed_strv( prefix = alloca(strlen(path) + 1); OBJECT_PATH_FOREACH_PREFIX(prefix, path) { - r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, names); + r = emit_properties_changed_on_interface(bus, prefix, path, interface, true, &found_interface, names); if (r != 0) return r; if (bus->nodes_modified) @@ -2212,7 +2227,7 @@ _public_ int sd_bus_emit_properties_changed_strv( } while (bus->nodes_modified); - return -ENOENT; + return found_interface ? 0 : -ENOENT; } _public_ int sd_bus_emit_properties_changed(