diff options
author | Wim Taymans <wtaymans@redhat.com> | 2019-07-15 17:13:39 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2019-07-15 17:13:39 +0200 |
commit | b0b379fc2a05e28909acdbbca454dfef916c72b5 (patch) | |
tree | 4e312f0e84dfde895f187d3053aa1e68c502ad3e /src | |
parent | 9b7d5c81e027f4af3682bd76866f0e364b1398f8 (diff) |
node: handle async node_set_param
We block the client doing the call until the operation completes
with a sync on the node.
Diffstat (limited to 'src')
-rw-r--r-- | src/pipewire/node.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/pipewire/node.c b/src/pipewire/node.c index e5885f18..3b817fc1 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -69,6 +69,11 @@ struct resource_data { uint32_t subscribe_ids[MAX_PARAMS]; uint32_t n_subscribe_ids; + + /* for async replies */ + int seq; + int end; + struct spa_hook listener; }; /** \endcond */ @@ -384,21 +389,45 @@ static int node_subscribe_params(void *object, uint32_t *ids, uint32_t n_ids) return 0; } +static void result_node_sync(void *data, int seq, int res, uint32_t type, const void *result) +{ + struct resource_data *d = data; + + pw_log_debug("sync result %d %d (%d/%d)", res, seq, d->seq, d->end); + if (seq == d->end) { + spa_hook_remove(&d->listener); + pw_client_set_busy(d->resource->client, false); + } +} + static int node_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); struct pw_node *node = data->node; + struct pw_client *client = resource->client; int res; + static const struct spa_node_events node_events = { + SPA_VERSION_NODE_EVENTS, + .result = result_node_sync, + }; pw_log_debug("resource %p: set param %s %08x", resource, spa_debug_type_find_name(spa_type_param, id), flags); - if ((res = spa_node_set_param(node->node, id, flags, param)) < 0) { + res = spa_node_set_param(node->node, id, flags, param); + + if (res < 0) { pw_log_error("resource %p: %d error %d (%s)", resource, resource->id, res, spa_strerror(res)); pw_resource_error(resource, res, spa_strerror(res)); + } else if (SPA_RESULT_IS_ASYNC(res)) { + spa_node_add_listener(node->node, &data->listener, + &node_events, data); + data->seq = res; + data->end = spa_node_sync(node->node, res); + pw_client_set_busy(client, true); } return 0; } |