diff --git a/src/pipewire/impl-client.c b/src/pipewire/impl-client.c index 4fd12575a..282a96249 100644 --- a/src/pipewire/impl-client.c +++ b/src/pipewire/impl-client.c @@ -58,36 +58,46 @@ static struct pw_permission * find_permission(struct pw_impl_client *client, uint32_t id) { struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this); - struct pw_permission *p, *def = NULL; + struct pw_permission *p; + uint32_t idx = id + 1; - pw_array_for_each(p, &impl->permissions) { - if (p->id == id && p->permissions != PW_PERM_INVALID) - return p; - else if (def == NULL && p->id == PW_ID_ANY) - def = p; - } - return def; + if (id == PW_ID_ANY) + goto do_default; + + if (!pw_array_check_index(&impl->permissions, idx, struct pw_permission)) + goto do_default; + + p = pw_array_get_unchecked(&impl->permissions, idx, struct pw_permission); + if (p->permissions == PW_PERM_INVALID) + goto do_default; + + return p; + +do_default: + return pw_array_get_unchecked(&impl->permissions, 0, struct pw_permission); } static struct pw_permission *ensure_permissions(struct pw_impl_client *client, uint32_t id) { struct impl *impl = SPA_CONTAINER_OF(client, struct impl, this); - struct pw_permission *p, *free = NULL; + struct pw_permission *p; + uint32_t idx = id + 1; + size_t len, i; - pw_array_for_each(p, &impl->permissions) { - if (p->id == id) - return p; - else if (free == NULL && p->permissions == PW_PERM_INVALID) - free = p; - } - if (free == NULL) { - if ((free = pw_array_add(&impl->permissions, - sizeof(struct pw_permission))) == NULL) + len = pw_array_get_len(&impl->permissions, struct pw_permission); + if (len <= idx) { + size_t diff = idx - len + 1; + + p = pw_array_add(&impl->permissions, diff * sizeof(struct pw_permission)); + if (p == NULL) return NULL; + + for (i = 0; i < diff; i++) { + p[i] = PW_PERMISSION_INIT(len + i - 1, PW_PERM_INVALID); + } } - free->id = id; - free->permissions = PW_PERM_INVALID; - return free; + p = pw_array_get_unchecked(&impl->permissions, idx, struct pw_permission); + return p; } /** \endcond */ @@ -404,7 +414,7 @@ struct pw_impl_client *pw_context_create_client(struct pw_impl_core *core, goto error_free; } - pw_array_init(&impl->permissions, 64); + pw_array_init(&impl->permissions, 1024); p = pw_array_add(&impl->permissions, sizeof(struct pw_permission)); if (p == NULL) { res = -errno; @@ -679,7 +689,8 @@ int pw_impl_client_update_permissions(struct pw_impl_client *client, pw_log_warn("%p: invalid global %d", client, permissions[i].id); continue; } - if ((p = ensure_permissions(client, permissions[i].id)) == NULL) { + p = ensure_permissions(client, permissions[i].id); + if (p == NULL) { pw_log_warn("%p: can't ensure permission: %m", client); return -errno; }