From 6f412236d5c0b16b8570225189dba5f794868376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barnab=C3=A1s=20P=C5=91cze?= Date: Tue, 14 Dec 2021 14:39:38 +0100 Subject: [PATCH] pulse-server: stream: only remove from list if pending Only call `spa_list_remove()` in `stream_free()` if the stream is pending. `spa_list_remove()` does not reinitialize the list node, therefore calling `spa_list_remove()` again after the stream has been removed from the pending list will corrupt the pending list of the client. --- src/modules/module-protocol-pulse/pulse-server.c | 7 +++++-- src/modules/module-protocol-pulse/stream.c | 3 ++- src/modules/module-protocol-pulse/stream.h | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index c98ae4f3b..a474bfa14 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -728,6 +728,7 @@ static void manager_added(void *data, struct pw_manager_object *o) if (peer) { reply_create_stream(s, peer); spa_list_remove(&s->link); + s->pending = false; } } @@ -1070,10 +1071,12 @@ static void stream_param_changed(void *data, uint32_t id, const struct spa_pod * /* if peer exists, reply immediately, otherwise reply when the link is created */ peer = find_linked(stream->client->manager, stream->id, stream->direction); - if (peer) + if (peer) { reply_create_stream(stream, peer); - else + } else { spa_list_append(&stream->client->pending_streams, &stream->link); + stream->pending = true; + } } params[n_params++] = get_buffers_param(stream, &stream->attr, &b); diff --git a/src/modules/module-protocol-pulse/stream.c b/src/modules/module-protocol-pulse/stream.c index 946edbd50..9ba93492a 100644 --- a/src/modules/module-protocol-pulse/stream.c +++ b/src/modules/module-protocol-pulse/stream.c @@ -96,7 +96,8 @@ void stream_free(struct stream *stream) pw_log_debug("client %p: stream %p channel:%d", client, stream, stream->channel); - spa_list_remove(&stream->link); + if (stream->pending) + spa_list_remove(&stream->link); if (stream->drain_tag) reply_error(client, -1, stream->drain_tag, -ENOENT); diff --git a/src/modules/module-protocol-pulse/stream.h b/src/modules/module-protocol-pulse/stream.h index 790e0300c..12ba25aff 100644 --- a/src/modules/module-protocol-pulse/stream.h +++ b/src/modules/module-protocol-pulse/stream.h @@ -106,6 +106,7 @@ struct stream { unsigned int in_prebuf:1; unsigned int done:1; unsigned int killed:1; + unsigned int pending:1; }; struct stream *stream_new(struct client *client, enum stream_type type, uint32_t create_tag,