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.
This commit is contained in:
Wim Taymans 2020-06-24 14:23:41 +02:00
parent d560499054
commit 5feedbfd42
4 changed files with 44 additions and 13 deletions

View file

@ -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,
&registry_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,
&registry_events, c);
}
pa_context_ensure_registry(c);
o = pa_operation_new(c, NULL, on_success, sizeof(struct success_data));
d = o->userdata;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}