mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
pulse-server: reply async to some requests
Trigger a roundtrip before we send the reply to the client for many methods like set_volume/set_mute etc. this ensure that we get the updated information from the server before we reply so that a subsequent query returns the up-to-data information. Fixes #868
This commit is contained in:
parent
808b54bc19
commit
d29bdf64ee
1 changed files with 68 additions and 8 deletions
|
|
@ -117,6 +117,13 @@ struct client;
|
|||
|
||||
#include "sample.c"
|
||||
|
||||
struct operation {
|
||||
struct spa_list link;
|
||||
struct client *client;
|
||||
int seq;
|
||||
uint32_t tag;
|
||||
};
|
||||
|
||||
struct client {
|
||||
struct spa_list link;
|
||||
struct impl *impl;
|
||||
|
|
@ -133,6 +140,7 @@ struct client {
|
|||
struct pw_properties *props;
|
||||
|
||||
struct pw_core *core;
|
||||
struct spa_hook core_listener;
|
||||
struct pw_manager *manager;
|
||||
struct spa_hook manager_listener;
|
||||
|
||||
|
|
@ -275,6 +283,7 @@ struct impl {
|
|||
#include "collect.c"
|
||||
#include "module.c"
|
||||
|
||||
|
||||
static void sample_free(struct sample *sample)
|
||||
{
|
||||
struct impl *impl = sample->impl;
|
||||
|
|
@ -480,6 +489,35 @@ static int reply_error(struct client *client, uint32_t command, uint32_t tag, in
|
|||
return send_message(client, reply);
|
||||
}
|
||||
|
||||
static int operation_new(struct client *client, uint32_t tag)
|
||||
{
|
||||
struct operation *o;
|
||||
|
||||
if ((o = calloc(1, sizeof(*o))) == NULL)
|
||||
return -errno;
|
||||
|
||||
o->client = client;
|
||||
o->tag = tag;
|
||||
o->seq = pw_core_sync(client->core, PW_ID_CORE, 0);
|
||||
spa_list_append(&client->operations, &o->link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void operation_free(struct operation *o)
|
||||
{
|
||||
spa_list_remove(&o->link);
|
||||
free(o);
|
||||
}
|
||||
|
||||
static void operation_complete(struct operation *o)
|
||||
{
|
||||
struct client *client = o->client;
|
||||
|
||||
pw_log_info(NAME" %p: [%s] tag:%u complete", client, client->name, o->tag);
|
||||
reply_simple_ack(o->client, o->tag);
|
||||
operation_free(o);
|
||||
}
|
||||
|
||||
#include "extension.c"
|
||||
|
||||
static int send_underflow(struct stream *stream, int64_t offset, uint32_t underrun_for)
|
||||
|
|
@ -980,6 +1018,22 @@ static void manager_metadata(void *data, struct pw_manager_object *o,
|
|||
}
|
||||
}
|
||||
|
||||
static void client_core_done(void *data, uint32_t id, int seq)
|
||||
{
|
||||
struct client *client = data;
|
||||
struct operation *o, *t;
|
||||
|
||||
spa_list_for_each_safe(o, t, &client->operations, link) {
|
||||
if (o->seq == seq)
|
||||
operation_complete(o);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pw_core_events client_core_events = {
|
||||
PW_VERSION_CORE_EVENTS,
|
||||
.done = client_core_done,
|
||||
};
|
||||
|
||||
static const struct pw_manager_events manager_events = {
|
||||
PW_VERSION_MANAGER_EVENTS,
|
||||
.sync = manager_sync,
|
||||
|
|
@ -1028,6 +1082,8 @@ static int do_set_client_name(struct client *client, uint32_t command, uint32_t
|
|||
goto error;
|
||||
}
|
||||
client->connect_tag = tag;
|
||||
pw_core_add_listener(client->core, &client->core_listener,
|
||||
&client_core_events, client);
|
||||
pw_manager_add_listener(client->manager, &client->manager_listener,
|
||||
&manager_events, client);
|
||||
} else {
|
||||
|
|
@ -3108,7 +3164,7 @@ static int do_set_stream_volume(struct client *client, uint32_t command, uint32_
|
|||
return res;
|
||||
}
|
||||
done:
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_set_stream_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -3159,7 +3215,7 @@ static int do_set_stream_mute(struct client *client, uint32_t command, uint32_t
|
|||
return res;
|
||||
}
|
||||
done:
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_set_volume(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -3224,7 +3280,7 @@ static int do_set_volume(struct client *client, uint32_t command, uint32_t tag,
|
|||
return res;
|
||||
|
||||
done:
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -3288,7 +3344,7 @@ static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, st
|
|||
if (res < 0)
|
||||
return res;
|
||||
done:
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_set_port(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -3344,7 +3400,7 @@ static int do_set_port(struct client *client, uint32_t command, uint32_t tag, st
|
|||
if ((res = set_card_port(card, device_id, port_id)) < 0)
|
||||
return res;
|
||||
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_set_port_latency_offset(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -3412,7 +3468,7 @@ static int do_set_port_latency_offset(struct client *client, uint32_t command, u
|
|||
if (res < 0)
|
||||
break;
|
||||
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
|
@ -4827,7 +4883,7 @@ static int do_set_profile(struct client *client, uint32_t command, uint32_t tag,
|
|||
SPA_PARAM_PROFILE_index, SPA_POD_Int(profile_id),
|
||||
SPA_PARAM_PROFILE_save, SPA_POD_Bool(true)));
|
||||
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_set_default(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -4900,7 +4956,7 @@ static int do_suspend(struct client *client, uint32_t command, uint32_t tag, str
|
|||
cmd = SPA_NODE_COMMAND_Suspend;
|
||||
pw_node_send_command((struct pw_node*)o->proxy, &SPA_NODE_COMMAND_INIT(cmd));
|
||||
}
|
||||
return reply_simple_ack(client, tag);
|
||||
return operation_new(client, tag);
|
||||
}
|
||||
|
||||
static int do_move_stream(struct client *client, uint32_t command, uint32_t tag, struct message *m)
|
||||
|
|
@ -5330,6 +5386,7 @@ static void client_free(struct client *client)
|
|||
struct impl *impl = client->impl;
|
||||
struct message *msg;
|
||||
struct pending_sample *p;
|
||||
struct operation *o;
|
||||
|
||||
pw_log_info(NAME" %p: client %p free", impl, client);
|
||||
|
||||
|
|
@ -5343,6 +5400,9 @@ static void client_free(struct client *client)
|
|||
spa_list_consume(msg, &client->out_messages, link)
|
||||
message_free(impl, msg, true, false);
|
||||
|
||||
spa_list_consume(o, &client->operations, link)
|
||||
operation_free(o);
|
||||
|
||||
if (client->core) {
|
||||
client->disconnecting = true;
|
||||
pw_core_disconnect(client->core);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue