mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
pulse-server: pending-sample: handle client disconnection correctly
Previously, a client disconnecting while a sample was playing could lead to issues. For example, if a client disconnected before the "ready" signal of the sample-play arrives, `operation_new_cb()` would be called and that would try to use the client's pw_manager, however, that has previously been destroyed in `client_disconnect()`. If the client disconnected after the "ready" signal but before the reply has been sent, then `sample_play_ready_reply()` would never be called since operations are completed via the client's pw_manager which would already be destroyed at that point. Fix this by installing a listener on the client, and properly cancelling the operation and making sure that the pending_sample is correctly destroyed.
This commit is contained in:
parent
bd510bf602
commit
2ba9881b4d
2 changed files with 18 additions and 0 deletions
|
|
@ -88,6 +88,21 @@ static const struct sample_play_events sample_play_events = {
|
|||
.done = on_sample_play_done,
|
||||
};
|
||||
|
||||
static void on_client_disconnect(void *data)
|
||||
{
|
||||
struct pending_sample *ps = data;
|
||||
|
||||
ps->replied = true;
|
||||
operation_free_by_tag(ps->client, ps->tag);
|
||||
|
||||
schedule_maybe_finish(ps);
|
||||
}
|
||||
|
||||
static const struct client_events client_events = {
|
||||
VERSION_CLIENT_EVENTS,
|
||||
.disconnect = on_client_disconnect,
|
||||
};
|
||||
|
||||
int pending_sample_new(struct client *client, struct sample *sample, struct pw_properties *props, uint32_t tag)
|
||||
{
|
||||
struct pending_sample *ps;
|
||||
|
|
@ -100,6 +115,7 @@ int pending_sample_new(struct client *client, struct sample *sample, struct pw_p
|
|||
ps->play = p;
|
||||
ps->tag = tag;
|
||||
sample_play_add_listener(p, &ps->listener, &sample_play_events, ps);
|
||||
client_add_listener(client, &ps->client_listener, &client_events, ps);
|
||||
spa_list_append(&client->pending_samples, &ps->link);
|
||||
client->ref++;
|
||||
|
||||
|
|
@ -113,6 +129,7 @@ void pending_sample_free(struct pending_sample *ps)
|
|||
|
||||
spa_list_remove(&ps->link);
|
||||
spa_hook_remove(&ps->listener);
|
||||
spa_hook_remove(&ps->client_listener);
|
||||
pw_work_queue_cancel(impl->work_queue, ps, SPA_ID_INVALID);
|
||||
|
||||
operation_free_by_tag(client, ps->tag);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct pending_sample {
|
|||
struct client *client;
|
||||
struct sample_play *play;
|
||||
struct spa_hook listener;
|
||||
struct spa_hook client_listener;
|
||||
uint32_t tag;
|
||||
unsigned replied:1;
|
||||
unsigned done:1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue