diff --git a/src/modules/module-protocol-native/protocol-footer.c b/src/modules/module-protocol-native/protocol-footer.c index f3c108505..bc4caa4a8 100644 --- a/src/modules/module-protocol-native/protocol-footer.c +++ b/src/modules/module-protocol-native/protocol-footer.c @@ -95,8 +95,8 @@ void marshal_client_footers(struct footer_client_global_state *state, struct pw_ { struct footer_builder fb = FOOTER_BUILDER_INIT(builder); - if (client->context->generation != state->last_sent_generation) { - state->last_sent_generation = client->context->generation; + if (client->context->generation != client->sent_generation) { + client->sent_generation = client->context->generation; pw_log_trace("impl-client %p: send server registry generation:%"PRIu64, client, client->context->generation); @@ -117,10 +117,11 @@ int demarshal_core_generation(void *object, struct spa_pod_parser *parser) if (spa_pod_parser_get_long(parser, &generation) < 0) return -EINVAL; - core->recv_generation = (uint64_t)generation; + core->recv_generation = SPA_MAX(core->recv_generation, + (uint64_t)generation); pw_log_trace("core %p: recv server registry generation:%"PRIu64, - core->core, generation); + core, generation); return 0; } @@ -133,7 +134,8 @@ int demarshal_client_generation(void *object, struct spa_pod_parser *parser) if (spa_pod_parser_get_long(parser, &generation) < 0) return -EINVAL; - client->recv_generation = (uint64_t)generation; + client->recv_generation = SPA_MAX(client->recv_generation, + (uint64_t)generation); pw_log_trace("impl-client %p: recv client registry generation:%"PRIu64, client, generation); diff --git a/src/modules/module-protocol-native/protocol-footer.h b/src/modules/module-protocol-native/protocol-footer.h index a097fd0a8..bdbec0430 100644 --- a/src/modules/module-protocol-native/protocol-footer.h +++ b/src/modules/module-protocol-native/protocol-footer.h @@ -44,7 +44,6 @@ struct footer_core_global_state { }; struct footer_client_global_state { - uint64_t last_sent_generation; }; struct footer_demarshal { diff --git a/src/pipewire/global.c b/src/pipewire/global.c index e67053073..aa2a048ce 100644 --- a/src/pipewire/global.c +++ b/src/pipewire/global.c @@ -139,6 +139,7 @@ int pw_global_register(struct pw_global *global) { struct pw_resource *registry; struct pw_context *context = global->context; + struct pw_impl_client *client; if (global->registered) return -EEXIST; @@ -150,8 +151,8 @@ int pw_global_register(struct pw_global *global) spa_list_for_each(registry, &context->registry_resource_list, link) { uint32_t permissions = pw_global_get_permissions(global, registry->client); - pw_log_debug("registry %p: global %d %08x serial:%"PRIu64, - registry, global->id, permissions, global->serial); + pw_log_debug("registry %p: global %d %08x serial:%"PRIu64" generation:%"PRIu64, + registry, global->id, permissions, global->serial, global->generation); if (PW_PERM_IS_R(permissions)) pw_registry_resource_global(registry, global->id, @@ -161,6 +162,25 @@ int pw_global_register(struct pw_global *global) &global->properties->dict); } + /* Ensure a message is sent also to clients without registries, to force + * generation number update. */ + spa_list_for_each(client, &context->client_list, link) { + uint32_t permissions; + + if (client->sent_generation >= context->generation) + continue; + if (!client->core_resource) + continue; + + permissions = pw_global_get_permissions(global, client); + if (PW_PERM_IS_R(permissions)) { + pw_log_debug("impl-client %p: (no registry) global %d %08x serial:%"PRIu64 + " generation:%"PRIu64, client, global->id, permissions, global->serial, + global->generation); + pw_core_resource_done(client->core_resource, global->id, 0); + } + } + pw_log_debug("%p: registered %u", global, global->id); pw_context_emit_global_added(context, global); diff --git a/src/pipewire/private.h b/src/pipewire/private.h index ea166dac0..b5ae51ab8 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -300,6 +300,7 @@ struct pw_impl_client { int recv_seq; /**< last received sequence number */ int send_seq; /**< last sender sequence number */ uint64_t recv_generation; /**< last received registry generation */ + uint64_t sent_generation; /**< last sent registry generation */ void *user_data; /**< extra user data */