mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
pulse-server: free pending sample reply
If the sample finished playing before we finished the roundtrip to get the sink_index, it will be destroyed. When the roundtrip completes, it will try to use invalid memoryy and crash. Make sure we destroy all pending replies before destroying the sample to avoid this problem. Fixes #2151
This commit is contained in:
parent
bf9ef440c3
commit
d7793501fd
4 changed files with 20 additions and 0 deletions
|
|
@ -66,6 +66,16 @@ void operation_free(struct operation *o)
|
|||
free(o);
|
||||
}
|
||||
|
||||
struct operation *operation_find(struct client *client, uint32_t tag)
|
||||
{
|
||||
struct operation *o;
|
||||
spa_list_for_each(o, &client->operations, link) {
|
||||
if (o->tag == tag)
|
||||
return o;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void operation_complete(struct operation *o)
|
||||
{
|
||||
struct client *client = o->client;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ int operation_new(struct client *client, uint32_t tag);
|
|||
int operation_new_cb(struct client *client, uint32_t tag,
|
||||
void (*callback) (void *data, struct client *client, uint32_t tag),
|
||||
void *data);
|
||||
struct operation *operation_find(struct client *client, uint32_t tag);
|
||||
void operation_free(struct operation *o);
|
||||
void operation_complete(struct operation *o);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "client.h"
|
||||
#include "internal.h"
|
||||
#include "log.h"
|
||||
#include "operation.h"
|
||||
#include "pending-sample.h"
|
||||
#include "sample-play.h"
|
||||
|
||||
|
|
@ -36,10 +37,14 @@ void pending_sample_free(struct pending_sample *ps)
|
|||
{
|
||||
struct client * const client = ps->client;
|
||||
struct impl * const impl = client->impl;
|
||||
struct operation *o;
|
||||
|
||||
spa_list_remove(&ps->link);
|
||||
spa_hook_remove(&ps->listener);
|
||||
pw_work_queue_cancel(impl->work_queue, ps, SPA_ID_INVALID);
|
||||
|
||||
if ((o = operation_find(client, ps->tag)) != NULL)
|
||||
operation_free(o);
|
||||
|
||||
sample_play_destroy(ps->play);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2353,6 +2353,10 @@ 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue