_public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL; _cleanup_free_ char *n = NULL; const char *match; int r; assert_return(track, -EINVAL); assert_return(service_name_is_valid(name), -EINVAL); r = hashmap_ensure_allocated(&track->names, &string_hash_ops); if (r < 0) return r; n = strdup(name); if (!n) return -ENOMEM; /* First, subscribe to this name */ match = MATCH_FOR_NAME(n); r = sd_bus_add_match(track->bus, &slot, match, on_name_owner_changed, track); if (r < 0) return r; r = hashmap_put(track->names, n, slot); if (r == -EEXIST) return 0; if (r < 0) return r; /* Second, check if it is currently existing, or maybe * doesn't, or maybe disappeared already. */ r = sd_bus_get_name_creds(track->bus, n, 0, NULL); if (r < 0) { hashmap_remove(track->names, n); return r; } n = NULL; slot = NULL; bus_track_remove_from_queue(track); track->modified = true; return 1; }
_public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) { if (!track) return NULL; assert(track->n_ref > 0); if (track->n_ref > 1) { track->n_ref--; return NULL; } if (track->in_list) LIST_REMOVE(tracks, track->bus->tracks, track); bus_track_remove_from_queue(track); hashmap_free_with_destructor(track->names, track_item_free); sd_bus_unref(track->bus); return mfree(track); }
void bus_track_dispatch(sd_bus_track *track) { int r; assert(track); assert(track->in_queue); assert(track->handler); bus_track_remove_from_queue(track); sd_bus_track_ref(track); r = track->handler(track, track->userdata); if (r < 0) log_debug_errno(r, "Failed to process track handler: %m"); else if (r == 0) bus_track_add_to_queue(track); sd_bus_track_unref(track); }
_public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) { const char *n; if (!track) return NULL; assert(track->n_ref > 0); if (track->n_ref > 1) { track->n_ref --; return NULL; } while ((n = hashmap_first_key(track->names))) sd_bus_track_remove_name(track, n); bus_track_remove_from_queue(track); hashmap_free(track->names); sd_bus_unref(track->bus); free(track); return NULL; }