From a9accd1668fddc17ad982cdb1d2967838c1a8161 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sat, 26 Feb 2022 00:31:33 +0200 Subject: [PATCH] protocol-native: footer pre_demarshal must come first Message footer should be handled before attempting to find the object the main message is sent to / checking permissions, because it is not aimed at a specific object. E.g. the registry generation updates should be handled regardless of whether the main message is valid or not, because the updates will not be re-sent. Fixes registry generation updates sometimes going missing. --- src/modules/module-protocol-native.c | 18 +++---- .../module-protocol-native/protocol-footer.c | 48 +++++++++---------- .../module-protocol-native/protocol-footer.h | 20 ++++---- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index e7112dfff..6d07233a7 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -116,7 +116,7 @@ struct client { int ref; - struct footer_proxy_global_state footer_state; + struct footer_core_global_state footer_state; unsigned int connected:1; unsigned int disconnecting:1; @@ -154,7 +154,7 @@ struct client_data { struct pw_protocol_native_connection *connection; struct spa_hook conn_listener; - struct footer_resource_global_state footer_state; + struct footer_client_global_state footer_state; unsigned int busy:1; unsigned int need_flush:1; @@ -261,6 +261,9 @@ process_messages(struct client_data *data) if (debug_messages) debug_msg("<<<<<< in", msg, false); + pre_demarshal(conn, msg, client, footer_client_demarshal, + SPA_N_ELEMENTS(footer_client_demarshal)); + resource = pw_impl_client_find_resource(client, msg->id); if (resource == NULL) { pw_resource_errorf(client->core_resource, @@ -297,8 +300,6 @@ process_messages(struct client_data *data) } pw_protocol_native_connection_enter(conn); - pre_demarshal(conn, msg, resource, footer_resource_demarshal, - SPA_N_ELEMENTS(footer_resource_demarshal)); res = demarshal[msg->opcode].func(resource, msg); pw_protocol_native_connection_leave(conn); if (res < 0) { @@ -817,6 +818,9 @@ process_remote(struct client *impl) if (debug_messages) debug_msg("<<<<<< in", msg, false); + pre_demarshal(conn, msg, this, footer_core_demarshal, + SPA_N_ELEMENTS(footer_core_demarshal)); + proxy = pw_core_find_proxy(this, msg->id); if (proxy == NULL || proxy->zombie) { if (proxy == NULL) @@ -844,8 +848,6 @@ process_remote(struct client *impl) } proxy->refcount++; pw_protocol_native_connection_enter(conn); - pre_demarshal(conn, msg, proxy, footer_proxy_demarshal, - SPA_N_ELEMENTS(footer_proxy_demarshal)); res = demarshal[msg->opcode].func(proxy, msg); pw_protocol_native_connection_leave(conn); pw_proxy_unref(proxy); @@ -1295,7 +1297,7 @@ static int impl_ext_end_proxy(struct pw_proxy *proxy, struct pw_core *core = proxy->core; struct client *impl = SPA_CONTAINER_OF(core->conn, struct client, this); assert_single_pod(builder); - marshal_proxy_footers(&impl->footer_state, proxy, builder); + marshal_core_footers(&impl->footer_state, core, builder); return core->send_seq = pw_protocol_native_connection_end(impl->connection, builder); } @@ -1324,7 +1326,7 @@ static int impl_ext_end_resource(struct pw_resource *resource, struct client_data *data = resource->client->user_data; struct pw_impl_client *client = resource->client; assert_single_pod(builder); - marshal_resource_footers(&data->footer_state, resource, builder); + marshal_client_footers(&data->footer_state, client, builder); return client->send_seq = pw_protocol_native_connection_end(data->connection, builder); } static const struct pw_protocol_native_ext protocol_ext_impl = { diff --git a/src/modules/module-protocol-native/protocol-footer.c b/src/modules/module-protocol-native/protocol-footer.c index 6b360a4b0..f3c108505 100644 --- a/src/modules/module-protocol-native/protocol-footer.c +++ b/src/modules/module-protocol-native/protocol-footer.c @@ -71,80 +71,80 @@ static void end_footer(struct footer_builder *fb) spa_pod_builder_pop(fb->builder, &fb->outer); } -void marshal_proxy_footers(struct footer_proxy_global_state *state, struct pw_proxy *proxy, +void marshal_core_footers(struct footer_core_global_state *state, struct pw_core *core, struct spa_pod_builder *builder) { struct footer_builder fb = FOOTER_BUILDER_INIT(builder); - if (proxy->core->recv_generation != state->last_recv_generation) { - state->last_recv_generation = proxy->core->recv_generation; + if (core->recv_generation != state->last_recv_generation) { + state->last_recv_generation = core->recv_generation; pw_log_trace("core %p: send client registry generation:%"PRIu64, - proxy->core, proxy->core->recv_generation); + core, core->recv_generation); - start_footer_entry(&fb, FOOTER_RESOURCE_OPCODE_GENERATION); - spa_pod_builder_long(fb.builder, proxy->core->recv_generation); + start_footer_entry(&fb, FOOTER_CLIENT_OPCODE_GENERATION); + spa_pod_builder_long(fb.builder, core->recv_generation); end_footer_entry(&fb); } end_footer(&fb); } -void marshal_resource_footers(struct footer_resource_global_state *state, struct pw_resource *resource, +void marshal_client_footers(struct footer_client_global_state *state, struct pw_impl_client *client, struct spa_pod_builder *builder) { struct footer_builder fb = FOOTER_BUILDER_INIT(builder); - if (resource->context->generation != state->last_sent_generation) { - state->last_sent_generation = resource->context->generation; + if (client->context->generation != state->last_sent_generation) { + state->last_sent_generation = client->context->generation; pw_log_trace("impl-client %p: send server registry generation:%"PRIu64, - resource->client, resource->context->generation); + client, client->context->generation); - start_footer_entry(&fb, FOOTER_RESOURCE_OPCODE_GENERATION); - spa_pod_builder_long(fb.builder, resource->context->generation); + start_footer_entry(&fb, FOOTER_CORE_OPCODE_GENERATION); + spa_pod_builder_long(fb.builder, client->context->generation); end_footer_entry(&fb); } end_footer(&fb); } -int demarshal_proxy_generation(void *object, struct spa_pod_parser *parser) +int demarshal_core_generation(void *object, struct spa_pod_parser *parser) { - struct pw_proxy *proxy = object; + struct pw_core *core = object; int64_t generation; if (spa_pod_parser_get_long(parser, &generation) < 0) return -EINVAL; - proxy->core->recv_generation = (uint64_t)generation; + core->recv_generation = (uint64_t)generation; pw_log_trace("core %p: recv server registry generation:%"PRIu64, - proxy->core, generation); + core->core, generation); return 0; } -int demarshal_resource_generation(void *object, struct spa_pod_parser *parser) +int demarshal_client_generation(void *object, struct spa_pod_parser *parser) { - struct pw_resource *resource = object; + struct pw_impl_client *client = object; int64_t generation; if (spa_pod_parser_get_long(parser, &generation) < 0) return -EINVAL; - resource->client->recv_generation = (uint64_t)generation; + client->recv_generation = (uint64_t)generation; pw_log_trace("impl-client %p: recv client registry generation:%"PRIu64, - resource->client, generation); + client, generation); return 0; } -const struct footer_demarshal footer_proxy_demarshal[FOOTER_PROXY_OPCODE_LAST] = { - [FOOTER_PROXY_OPCODE_GENERATION] = (struct footer_demarshal){ .demarshal = demarshal_proxy_generation }, +const struct footer_demarshal footer_core_demarshal[FOOTER_CORE_OPCODE_LAST] = { + [FOOTER_CORE_OPCODE_GENERATION] = (struct footer_demarshal){ .demarshal = demarshal_core_generation }, }; -const struct footer_demarshal footer_resource_demarshal[FOOTER_RESOURCE_OPCODE_LAST] = { - [FOOTER_RESOURCE_OPCODE_GENERATION] = (struct footer_demarshal){ .demarshal = demarshal_resource_generation }, +const struct footer_demarshal footer_client_demarshal[FOOTER_CLIENT_OPCODE_LAST] = { + [FOOTER_CLIENT_OPCODE_GENERATION] = (struct footer_demarshal){ .demarshal = demarshal_client_generation }, }; diff --git a/src/modules/module-protocol-native/protocol-footer.h b/src/modules/module-protocol-native/protocol-footer.h index 45d3a1d92..a097fd0a8 100644 --- a/src/modules/module-protocol-native/protocol-footer.h +++ b/src/modules/module-protocol-native/protocol-footer.h @@ -30,20 +30,20 @@ */ enum { - FOOTER_PROXY_OPCODE_GENERATION = 0, - FOOTER_PROXY_OPCODE_LAST + FOOTER_CORE_OPCODE_GENERATION = 0, + FOOTER_CORE_OPCODE_LAST }; enum { - FOOTER_RESOURCE_OPCODE_GENERATION = 0, - FOOTER_RESOURCE_OPCODE_LAST + FOOTER_CLIENT_OPCODE_GENERATION = 0, + FOOTER_CLIENT_OPCODE_LAST }; -struct footer_proxy_global_state { +struct footer_core_global_state { uint64_t last_recv_generation; }; -struct footer_resource_global_state { +struct footer_client_global_state { uint64_t last_sent_generation; }; @@ -51,10 +51,10 @@ struct footer_demarshal { int (*demarshal)(void *object, struct spa_pod_parser *parser); }; -extern const struct footer_demarshal footer_proxy_demarshal[FOOTER_PROXY_OPCODE_LAST]; -extern const struct footer_demarshal footer_resource_demarshal[FOOTER_RESOURCE_OPCODE_LAST]; +extern const struct footer_demarshal footer_core_demarshal[FOOTER_CORE_OPCODE_LAST]; +extern const struct footer_demarshal footer_client_demarshal[FOOTER_CLIENT_OPCODE_LAST]; -void marshal_proxy_footers(struct footer_proxy_global_state *state, struct pw_proxy *proxy, +void marshal_core_footers(struct footer_core_global_state *state, struct pw_core *core, struct spa_pod_builder *builder); -void marshal_resource_footers(struct footer_resource_global_state *state, struct pw_resource *resource, +void marshal_client_footers(struct footer_client_global_state *state, struct pw_impl_client *client, struct spa_pod_builder *builder);