From 5feedbfd422b257d4e6b6fe9c8c43c408133b339 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 24 Jun 2020 14:23:41 +0200 Subject: [PATCH] context: ensure the registry exists Make sure we are watching the registry before we try to enumerate objects. When we wait for new object info, resync the pending operations because they might depend on the info. --- pipewire-pulseaudio/src/context.c | 42 ++++++++++++++++++++-------- pipewire-pulseaudio/src/internal.h | 1 + pipewire-pulseaudio/src/introspect.c | 12 ++++++++ pipewire-pulseaudio/src/operation.c | 2 +- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/pipewire-pulseaudio/src/context.c b/pipewire-pulseaudio/src/context.c index 733a4d452..586cdea6e 100644 --- a/pipewire-pulseaudio/src/context.c +++ b/pipewire-pulseaudio/src/context.c @@ -224,6 +224,16 @@ static const char *str_efac(pa_subscription_event_type_t event) return "invalid"; } +static void global_sync(struct global *g) +{ + pa_operation *o; + pa_context *c = g->context; + + g->pending_seq = pw_proxy_sync(g->proxy, 0); + spa_list_for_each(o, &c->operations, link) + o->seq = g->pending_seq; +} + static void emit_event(pa_context *c, struct global *g, pa_subscription_event_type_t event) { if (c->subscribe_callback && (c->subscribe_mask & g->mask)) { @@ -254,6 +264,7 @@ static void update_device_props(struct global *g) pa_proplist_sets(i->proplist, PA_PROP_DEVICE_ICON_NAME, s); } + static void device_event_info(void *object, const struct pw_device_info *info) { struct global *g = object; @@ -299,7 +310,7 @@ static void device_event_info(void *object, const struct pw_device_info *info) } } } - g->pending_seq = pw_proxy_sync(g->proxy, 0); + global_sync(g); } static void device_event_param(void *object, int seq, @@ -400,7 +411,7 @@ static void node_event_info(void *object, const struct pw_node_info *info) g->subscribed = true; } } - g->pending_seq = pw_proxy_sync(g->proxy, 0); + global_sync(g); } static void parse_props(struct global *g, const struct spa_pod *param) @@ -490,7 +501,7 @@ static void module_event_info(void *object, const struct pw_module_info *info) i->argument = info->args; i->n_used = -1; i->auto_unload = false; - g->pending_seq = pw_proxy_sync(g->proxy, 0); + global_sync(g); } static const struct pw_module_events module_events = { @@ -530,7 +541,7 @@ static void client_event_info(void *object, const struct pw_client_info *info) i->driver = info->props ? spa_dict_lookup(info->props, PW_KEY_PROTOCOL) : NULL; } - g->pending_seq = pw_proxy_sync(g->proxy, 0); + global_sync(g); } static const struct pw_client_events client_events = { @@ -718,6 +729,7 @@ static int set_mask(pa_context *c, struct global *g) pw_proxy_add_object_listener(g->proxy, &g->object_listener, events, g); pw_proxy_add_listener(g->proxy, &g->proxy_listener, &proxy_events, g); g->destroy = destroy; + global_sync(g); } else { emit_event(c, g, PA_SUBSCRIPTION_EVENT_NEW); } @@ -830,7 +842,7 @@ static void core_error(void *data, uint32_t id, int seq, int res, const char *me static void core_done(void *data, uint32_t id, int seq) { pa_context *c = data; - pw_log_debug("done %d", seq); + pw_log_debug("done id:%u seq:%d", id, seq); complete_operations(c, seq); } @@ -859,6 +871,18 @@ static void on_success(pa_operation *o, void *userdata) pa_operation_done(o); } +void pa_context_ensure_registry(pa_context *c) +{ + if (c->registry != NULL) + return; + + c->registry = pw_core_get_registry(c->core, + PW_VERSION_REGISTRY, 0); + pw_registry_add_listener(c->registry, + &c->registry_listener, + ®istry_events, c); +} + SPA_EXPORT pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_context_success_cb_t cb, void *userdata) { @@ -872,13 +896,7 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c c->subscribe_mask = m; - if (c->registry == NULL) { - c->registry = pw_core_get_registry(c->core, - PW_VERSION_REGISTRY, 0); - pw_registry_add_listener(c->registry, - &c->registry_listener, - ®istry_events, c); - } + pa_context_ensure_registry(c); o = pa_operation_new(c, NULL, on_success, sizeof(struct success_data)); d = o->userdata; diff --git a/pipewire-pulseaudio/src/internal.h b/pipewire-pulseaudio/src/internal.h index d88130eb8..7ce68ff10 100644 --- a/pipewire-pulseaudio/src/internal.h +++ b/pipewire-pulseaudio/src/internal.h @@ -322,6 +322,7 @@ struct pa_context { struct global *pa_context_find_global(pa_context *c, uint32_t id); struct global *pa_context_find_global_by_name(pa_context *c, uint32_t mask, const char *name); struct global *pa_context_find_linked(pa_context *c, uint32_t id); +void pa_context_ensure_registry(pa_context *c); struct pa_mem { struct spa_list link; diff --git a/pipewire-pulseaudio/src/introspect.c b/pipewire-pulseaudio/src/introspect.c index 67f1bd546..00bc5dfda 100644 --- a/pipewire-pulseaudio/src/introspect.c +++ b/pipewire-pulseaudio/src/introspect.c @@ -255,6 +255,8 @@ pa_operation* pa_context_get_sink_info_list(pa_context *c, pa_sink_info_cb_t cb, PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + pa_context_ensure_registry(c); + o = pa_operation_new(c, NULL, sink_info_list, sizeof(struct sink_data)); d = o->userdata; d->context = c; @@ -724,6 +726,8 @@ pa_operation* pa_context_get_source_info_list(pa_context *c, pa_source_info_cb_t PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + pa_context_ensure_registry(c); + o = pa_operation_new(c, NULL, source_info_list, sizeof(struct source_data)); d = o->userdata; d->context = c; @@ -1070,6 +1074,8 @@ pa_operation* pa_context_get_module_info_list(pa_context *c, pa_module_info_cb_t PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + pa_context_ensure_registry(c); + o = pa_operation_new(c, NULL, module_info_list, sizeof(struct module_data)); d = o->userdata; d->context = c; @@ -1189,6 +1195,8 @@ pa_operation* pa_context_get_client_info_list(pa_context *c, pa_client_info_cb_t PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + pa_context_ensure_registry(c); + o = pa_operation_new(c, NULL, client_info_list, sizeof(struct client_data)); d = o->userdata; d->context = c; @@ -1393,6 +1401,7 @@ pa_operation* pa_context_get_card_info_list(pa_context *c, pa_card_info_cb_t cb, PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); pw_log_debug("context %p", c); + pa_context_ensure_registry(c); o = pa_operation_new(c, NULL, card_info_list, sizeof(struct card_data)); d = o->userdata; @@ -1707,6 +1716,7 @@ pa_operation* pa_context_get_sink_input_info_list(pa_context *c, pa_sink_input_i PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); pw_log_debug("context %p", c); + pa_context_ensure_registry(c); o = pa_operation_new(c, NULL, sink_input_info_list, sizeof(struct sink_input_data)); d = o->userdata; @@ -2015,6 +2025,8 @@ pa_operation* pa_context_get_source_output_info_list(pa_context *c, pa_source_ou PA_CHECK_VALIDITY_RETURN_NULL(c, c->state == PA_CONTEXT_READY, PA_ERR_BADSTATE); + pa_context_ensure_registry(c); + o = pa_operation_new(c, NULL, source_output_info_list, sizeof(struct source_output_data)); d = o->userdata; d->context = c; diff --git a/pipewire-pulseaudio/src/operation.c b/pipewire-pulseaudio/src/operation.c index 0a13911b7..b5f83133e 100644 --- a/pipewire-pulseaudio/src/operation.c +++ b/pipewire-pulseaudio/src/operation.c @@ -52,7 +52,7 @@ pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb int pa_operation_sync(pa_operation *o) { pa_context *c = o->context; - o->seq = pw_core_sync(c->core, 0, 0); + o->seq = pw_core_sync(c->core, PW_ID_CORE, 0); pw_log_debug("operation %p: sync %d", o, o->seq); return 0; }