From 0475adbd35bac6d466f6d7cc7441233d72381599 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 21 Feb 2022 08:57:15 +0100 Subject: [PATCH] pulse-server: wait for pending_sample to complete Wait the reply to be sent and the sample to complete playback before freeing the sample. Otherwise it might have been possible that the sample completes before the reply can be sent. --- .../module-protocol-pulse/pending-sample.h | 2 ++ .../module-protocol-pulse/pulse-server.c | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/modules/module-protocol-pulse/pending-sample.h b/src/modules/module-protocol-pulse/pending-sample.h index 343138ad8..f467ca7ba 100644 --- a/src/modules/module-protocol-pulse/pending-sample.h +++ b/src/modules/module-protocol-pulse/pending-sample.h @@ -39,6 +39,8 @@ struct pending_sample { struct sample_play *play; struct spa_hook listener; uint32_t tag; + unsigned ready:1; + unsigned done:1; }; void pending_sample_free(struct pending_sample *ps); diff --git a/src/modules/module-protocol-pulse/pulse-server.c b/src/modules/module-protocol-pulse/pulse-server.c index ac8974a34..65dcb6bb0 100644 --- a/src/modules/module-protocol-pulse/pulse-server.c +++ b/src/modules/module-protocol-pulse/pulse-server.c @@ -2327,6 +2327,12 @@ static struct pw_manager_object *find_device(struct client *client, return o; } +static void sample_play_finish(struct pending_sample *ps) +{ + pending_sample_free(ps); + client_unref(ps->client); +} + static void sample_play_ready_reply(void *data, struct client *client, uint32_t tag) { struct pending_sample *ps = data; @@ -2336,6 +2342,8 @@ static void sample_play_ready_reply(void *data, struct client *client, uint32_t pw_log_info("[%s] PLAY_SAMPLE tag:%u index:%u", client->name, ps->tag, index); + ps->ready = true; + reply = reply_new(client, ps->tag); if (client->version >= 13) message_put(reply, @@ -2343,6 +2351,9 @@ static void sample_play_ready_reply(void *data, struct client *client, uint32_t TAG_INVALID); client_queue_message(client, reply); + + if (ps->done) + sample_play_finish(ps); } static void sample_play_ready(void *data, uint32_t id) @@ -2355,14 +2366,9 @@ static void sample_play_ready(void *data, uint32_t id) static void on_sample_done(void *obj, void *data, int res, uint32_t id) { struct pending_sample *ps = obj; - struct client *client = ps->client; - struct operation *o; - - if ((o = operation_find(client, ps->tag)) != NULL) - operation_complete(o); - - pending_sample_free(ps); - client_unref(client); + ps->done = true; + if (ps->ready) + sample_play_finish(ps); } static void sample_play_done(void *data, int res)