node: improve async handling

Remove the done and error callbacks. The error callback is in an
error message. The done callback is replace with spa_pending.

Make enum_params take a callback and data for the results. This allows
us to push the results one after another to the app and avoids ownership
issues of the passed data. We can then extend this to handle the async
case by doing a _wait call with a spa_pending+callback+data that will
be called when the _enum_params returns and async result.
Add a sync method.

All methods can now return SPA_RESULT_IS_ASYNC return values and you
can use spa_node_wait() to register a callback when they complete
with optional extra parameters. This makes it easier to sync and
handle the reply.

Make helper methods to simulate the sync enum_params behaviour for
sync nodes.

Let the transport generate the sequence number for pw_resource_sync()
and pw_proxy_sync(). That way we don't need to keep track of numbers
ourselves and we can match the reply to the request easily.
This commit is contained in:
Wim Taymans 2019-02-20 17:51:05 +01:00
parent b743518f78
commit 7b12212eeb
67 changed files with 1894 additions and 1209 deletions

View file

@ -122,10 +122,9 @@ struct impl {
#define GET_PORT(this,d,p) (d == SPA_DIRECTION_INPUT ? GET_IN_PORT(this,p) : GET_OUT_PORT(this,p))
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **param,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
return -ENOTSUP;
}
@ -274,13 +273,13 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int port_enum_formats(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t *index,
uint32_t index,
struct spa_pod **param,
struct spa_pod_builder *builder)
{
struct impl *this = SPA_CONTAINER_OF(node, struct impl, node);
switch (*index) {
switch (index) {
case 0:
if (this->have_format) {
*param = spa_format_audio_raw_build(builder, SPA_PARAM_EnumFormat,
@ -304,21 +303,22 @@ static int port_enum_formats(struct spa_node *node,
static int
impl_node_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct impl *this;
struct port *port;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct impl, node);
@ -326,6 +326,8 @@ impl_node_port_enum_params(struct spa_node *node,
port = GET_PORT(this, direction, port_id);
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -338,32 +340,32 @@ impl_node_port_enum_params(struct spa_node *node,
SPA_PARAM_Meta,
SPA_PARAM_IO };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
}
case SPA_PARAM_EnumFormat:
if ((res = port_enum_formats(node, direction, port_id, index, &param, &b)) <= 0)
if ((res = port_enum_formats(node, direction, port_id, result.next, &param, &b)) <= 0)
return res;
break;
case SPA_PARAM_Format:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_format_audio_raw_build(builder, id, &this->format.info.raw);
param = spa_format_audio_raw_build(&b, id, &this->format.info.raw);
break;
case SPA_PARAM_Buffers:
if (!port->have_format)
return -EIO;
if (*index > 0)
if (result.next > 0)
return 0;
param = spa_pod_builder_add_object(&b,
@ -382,7 +384,7 @@ impl_node_port_enum_params(struct spa_node *node,
if (!port->have_format)
return -EIO;
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamMeta, id,
@ -395,7 +397,7 @@ impl_node_port_enum_params(struct spa_node *node,
break;
case SPA_PARAM_IO:
switch (*index) {
switch (result.next) {
case 0:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamIO, id,
@ -422,12 +424,18 @@ impl_node_port_enum_params(struct spa_node *node,
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static int clear_buffers(struct impl *this, struct port *port)

View file

@ -146,6 +146,8 @@ struct node {
uint32_t n_params;
struct spa_pod **params;
struct spa_list pending_list;
};
struct impl {
@ -163,6 +165,7 @@ struct impl {
struct spa_hook resource_listener;
struct pw_array mems;
uint32_t init_seq;
int fds[2];
int other_fds[2];
@ -352,34 +355,47 @@ static void mix_clear(struct node *this, struct mix *mix)
}
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
result.next = start;
while (true) {
struct spa_pod *param;
if (*index >= this->n_params)
if (result.next >= this->n_params)
return 0;
param = this->params[(*index)++];
param = this->params[result.next++];
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if (spa_pod_filter(&b, &result.param, param, filter) != 0)
continue;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
break;
}
return 1;
return 0;
}
static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flags,
@ -392,7 +408,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag
this = SPA_CONTAINER_OF(node, struct node, node);
if (this->resource == NULL)
return 0;
return -EIO;
return pw_client_node_resource_set_param(this->resource, id, flags, param);
}
@ -410,9 +426,12 @@ static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
if (this->resource == NULL)
if (impl->this.flags & 1)
return 0;
if (this->resource == NULL)
return -EIO;
if (data) {
if ((mem = pw_memblock_find(data)) == NULL)
return -EINVAL;
@ -451,7 +470,7 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
this = SPA_CONTAINER_OF(node, struct node, node);
if (this->resource == NULL)
return 0;
return -EIO;
pw_log_debug("client-node %p: send command %d", node, SPA_COMMAND_TYPE(command));
return pw_client_node_resource_command(this->resource, command);
@ -460,9 +479,9 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman
static void emit_port_info(struct node *this, struct port *port)
{
if (this->callbacks && this->callbacks->port_info) {
this->callbacks->port_info(this->callbacks_data, port->direction, port->id, &port->info);
}
if (this->callbacks && this->callbacks->port_info)
this->callbacks->port_info(this->callbacks_data,
port->direction, port->id, &port->info);
}
static int
@ -471,6 +490,7 @@ impl_node_set_callbacks(struct spa_node *node,
void *data)
{
struct node *this;
int res = 0;
uint32_t i;
spa_return_val_if_fail(node != NULL, -EINVAL);
@ -479,6 +499,8 @@ impl_node_set_callbacks(struct spa_node *node,
this->callbacks = callbacks;
this->callbacks_data = data;
pw_log_debug("client-node %p: callbacks %p", this, callbacks);
for (i = 0; i < MAX_INPUTS; i++) {
if (this->in_ports[i])
emit_port_info(this, this->in_ports[i]);
@ -487,17 +509,50 @@ impl_node_set_callbacks(struct spa_node *node,
if (this->out_ports[i])
emit_port_info(this, this->out_ports[i]);
}
return 0;
if (callbacks && this->resource)
res = pw_resource_sync(this->resource);
return res;
}
static int
impl_node_sync(struct spa_node *node, uint32_t seq)
impl_node_sync(struct spa_node *node)
{
struct node *this;
spa_return_val_if_fail(node != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
pw_log_debug("client-node %p: sync %u", node, seq);
return pw_resource_sync(this->resource, seq);
pw_log_debug("client-node %p: sync", node);
if (this->resource == NULL)
return -EIO;
return pw_resource_sync(this->resource);
}
static int
impl_node_wait(struct spa_node *node, int res, struct spa_pending *pending,
spa_result_func_t func, void *data)
{
struct node *this;
int seq;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
spa_return_val_if_fail(pending != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
pw_log_debug("client-node %p: wait %d %d", node, res, SPA_RESULT_ASYNC_SEQ(res));
if (this->resource == NULL)
return -EIO;
seq = pw_resource_sync(this->resource);
pending->seq = seq;
pending->res = res;
pending->func = func;
pending->data = data;
spa_list_append(&this->pending_list, &pending->link);
return seq;
}
static void
@ -520,7 +575,7 @@ do_update_port(struct node *this,
port->params = realloc(port->params, port->n_params * sizeof(struct spa_pod *));
for (i = 0; i < port->n_params; i++) {
port->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
port->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
if (port->params[i] && spa_pod_is_object_id(port->params[i], SPA_PARAM_Format))
port->have_format = true;
@ -608,17 +663,21 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int
impl_node_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
struct port *port;
uint8_t buffer[1024];
struct spa_pod_builder b = { 0 };
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
@ -629,21 +688,30 @@ impl_node_port_enum_params(struct spa_node *node,
pw_log_debug("client-node %p: port %d.%d", this,
direction, port_id);
result.next = start;
while (true) {
struct spa_pod *param;
if (*index >= port->n_params)
if (result.next >= port->n_params)
return 0;
param = port->params[(*index)++];
param = port->params[result.next++];
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
continue;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
break;
}
return 1;
return 0;
}
static int
@ -661,7 +729,7 @@ impl_node_port_set_param(struct spa_node *node,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
if (this->resource == NULL)
return 0;
return -EIO;
pw_log_debug("node %p: port %d.%d add param %s %d", this,
direction, port_id,
@ -692,7 +760,7 @@ static int do_port_set_io(struct impl *impl,
spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL);
if (this->resource == NULL)
return 0;
return -EIO;
port = GET_PORT(this, direction, port_id);
@ -781,7 +849,7 @@ do_port_use_buffers(struct impl *impl,
mix->n_buffers = n_buffers;
if (this->resource == NULL)
return 0;
return -EIO;
for (i = 0; i < n_buffers; i++) {
struct buffer *b = &mix->buffers[i];
@ -963,7 +1031,7 @@ client_node_update(void *data,
this->params = realloc(this->params, this->n_params * sizeof(struct spa_pod *));
for (i = 0; i < this->n_params; i++)
this->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
this->params[i] = params[i] ? spa_pod_copy(params[i]) : NULL;
}
if (change_mask & PW_CLIENT_NODE_UPDATE_PROPS) {
pw_node_update_properties(impl->this.node, props);
@ -1068,6 +1136,7 @@ static const struct spa_node impl_node = {
NULL,
.set_callbacks = impl_node_set_callbacks,
.sync = impl_node_sync,
.wait = impl_node_wait,
.enum_params = impl_node_enum_params,
.set_param = impl_node_set_param,
.set_io = impl_node_set_io,
@ -1109,6 +1178,7 @@ node_init(struct node *this,
}
this->node = impl_node;
spa_list_init(&this->pending_list);
init_ios(this->ios);
@ -1174,18 +1244,24 @@ static void client_node_resource_error(void *data, int res, const char *message)
struct impl *impl = data;
struct node *this = &impl->node;
pw_log_error("client-node %p: error %d: %s", this, res, message);
if (this->callbacks && this->callbacks->error)
this->callbacks->error(this->callbacks_data, res, message);
}
static void client_node_resource_done(void *data, uint32_t seq)
{
struct impl *impl = data;
struct node *this = &impl->node;
struct spa_pending *p, *t;
pw_log_debug("client-node %p: done %d", this, seq);
if (this->callbacks && this->callbacks->done)
this->callbacks->done(this->callbacks_data, SPA_RESULT_ASYNC_SEQ(seq));
spa_list_for_each_safe(p, t, &this->pending_list, link) {
pw_log_debug("client-node %p: check %d", this, p->seq);
if (p->seq == (int) seq) {
pw_log_debug("client-node %p: found %d", this, p->res);
p->func(p->data, p->res, 0, NULL);
spa_list_remove(&p->link);
}
}
}
void pw_client_node_registered(struct pw_client_node *this, uint32_t node_id)
@ -1318,14 +1394,13 @@ static const struct pw_port_implementation port_impl = {
static int
impl_mix_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct port *port = SPA_CONTAINER_OF(node, struct port, mix_node);
return impl_node_port_enum_params(&port->node->node, direction, port->id,
id, index, filter, result, builder);
id, start, num, filter, func, data);
}
static int
@ -1597,6 +1672,8 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
support = pw_core_get_support(impl->core, &n_support);
node_init(&impl->node, NULL, support, n_support);
impl->node.impl = impl;
impl->node.resource = resource;
this->flags = do_register ? 0 : 1;
pw_map_init(&impl->io_map, 64, 64);
pw_array_init(&impl->mems, 64);
@ -1610,7 +1687,6 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
pw_resource_get_client(this->resource),
parent,
name,
PW_SPA_NODE_FLAG_ASYNC |
(do_register ? 0 : PW_SPA_NODE_FLAG_NO_REGISTER),
&impl->node.node,
NULL,
@ -1619,6 +1695,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
goto error_no_node;
this->node->remote = true;
this->flags = 0;
spa_graph_node_set_callbacks(&this->node->rt.root, &root_impl, this);
@ -1630,13 +1707,10 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
&client_node_methods,
impl);
impl->node.resource = this->resource;
this->node->port_user_data_size = sizeof(struct port);
pw_node_add_listener(this->node, &impl->node_listener, &node_events, impl);
pw_resource_sync(this->resource, 0);
return this;
error_no_node:

View file

@ -41,6 +41,7 @@ struct pw_client_node {
struct pw_resource *resource;
struct pw_global *parent;
uint32_t flags;
};
struct pw_client_node *

View file

@ -34,6 +34,7 @@
#include <sys/eventfd.h>
#include <spa/node/node.h>
#include <spa/node/utils.h>
#include <spa/buffer/alloc.h>
#include <spa/pod/parser.h>
#include <spa/pod/filter.h>
@ -68,8 +69,6 @@ struct node {
const struct spa_node_callbacks *callbacks;
void *callbacks_data;
uint32_t seq;
};
struct impl {
@ -83,7 +82,6 @@ struct impl {
struct spa_hook node_listener;
struct spa_hook client_node_listener;
struct spa_hook resource_listener;
enum spa_direction direction;
@ -110,24 +108,28 @@ struct impl {
/** \endcond */
static int impl_node_enum_params(struct spa_node *node,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
struct impl *impl;
struct spa_pod *param;
struct spa_pod_builder b = { 0 };
uint8_t buffer[1024];
struct spa_result_node_enum_params result;
uint32_t count = 0;
int res;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
result.next = start;
next:
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -138,10 +140,10 @@ static int impl_node_enum_params(struct spa_node *node,
SPA_PARAM_EnumFormat,
SPA_PARAM_Format };
if (*index < SPA_N_ELEMENTS(list))
if (result.next < SPA_N_ELEMENTS(list))
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_ParamList, id,
SPA_PARAM_LIST_id, SPA_POD_Id(list[*index]));
SPA_PARAM_LIST_id, SPA_POD_Id(list[result.next]));
else
return 0;
break;
@ -149,8 +151,7 @@ static int impl_node_enum_params(struct spa_node *node,
case SPA_PARAM_Props:
if (impl->adapter != impl->cnode) {
return spa_node_enum_params(impl->adapter,
id, index,
filter, result, builder);
id, start, num, filter, func, data);
}
return 0;
@ -158,18 +159,24 @@ static int impl_node_enum_params(struct spa_node *node,
case SPA_PARAM_Format:
return spa_node_port_enum_params(impl->cnode,
impl->direction, 0,
id, index,
filter, result, builder);
id, start, num,
filter, func, data);
default:
return -ENOENT;
}
(*index)++;
result.next++;
if (spa_pod_filter(builder, result, param, filter) < 0)
if (spa_pod_filter(&b, &result.param, param, filter) < 0)
goto next;
return 1;
if ((res = func(data, count, 1, &result)) != 0)
return res;
if (++count != num)
goto next;
return 0;
}
static void try_link_controls(struct impl *impl)
@ -323,11 +330,11 @@ impl_node_set_callbacks(struct spa_node *node,
if (this->callbacks && impl->adapter && impl->adapter != impl->cnode)
spa_node_set_callbacks(impl->adapter, &adapter_node_callbacks, impl);
return 0;
return spa_node_sync(impl->cnode);
}
static int
impl_node_sync(struct spa_node *node, uint32_t seq)
impl_node_sync(struct spa_node *node)
{
struct node *this;
struct impl *impl;
@ -337,7 +344,22 @@ impl_node_sync(struct spa_node *node, uint32_t seq)
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
return spa_node_sync(impl->cnode, seq);
return spa_node_sync(impl->cnode);
}
static int
impl_node_wait(struct spa_node *node, int seq, struct spa_pending *pending,
spa_result_func_t func, void *data)
{
struct node *this;
struct impl *impl;
spa_return_val_if_fail(node != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
return spa_node_wait(impl->cnode, seq, pending, func, data);
}
static int
@ -389,17 +411,16 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3
static int
impl_node_port_enum_params(struct spa_node *node,
enum spa_direction direction, uint32_t port_id,
uint32_t id, uint32_t *index,
uint32_t id, uint32_t start, uint32_t num,
const struct spa_pod *filter,
struct spa_pod **result,
struct spa_pod_builder *builder)
spa_result_func_t func, void *data)
{
struct node *this;
struct impl *impl;
spa_return_val_if_fail(node != NULL, -EINVAL);
spa_return_val_if_fail(index != NULL, -EINVAL);
spa_return_val_if_fail(builder != NULL, -EINVAL);
spa_return_val_if_fail(num != 0, -EINVAL);
spa_return_val_if_fail(func != NULL, -EINVAL);
this = SPA_CONTAINER_OF(node, struct node, node);
impl = this->impl;
@ -408,7 +429,7 @@ impl_node_port_enum_params(struct spa_node *node,
return -EINVAL;
return spa_node_port_enum_params(impl->adapter, direction, port_id, id,
index, filter, result, builder);
start, num, filter, func, data);
}
static int debug_params(struct impl *impl, struct spa_node *node,
@ -426,11 +447,11 @@ static int debug_params(struct impl *impl, struct spa_node *node,
state = 0;
while (true) {
spa_pod_builder_init(&b, buffer, sizeof(buffer));
res = spa_node_port_enum_params(node,
res = spa_node_port_enum_params_sync(node,
direction, port_id,
id, &state,
NULL, &param, &b);
if (res <= 0) {
if (res != 1) {
if (res < 0)
spa_log_error(this->log, " error: %s", spa_strerror(res));
break;
@ -460,11 +481,11 @@ static int negotiate_format(struct impl *impl)
spa_log_debug(this->log, NAME "%p: negiotiate", impl);
state = 0;
if ((res = spa_node_port_enum_params(impl->adapter_mix,
if ((res = spa_node_port_enum_params_sync(impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
SPA_PARAM_EnumFormat, &state,
NULL, &format, &b)) <= 0) {
NULL, &format, &b)) != 1) {
debug_params(impl, impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
@ -473,10 +494,10 @@ static int negotiate_format(struct impl *impl)
}
state = 0;
if ((res = spa_node_port_enum_params(impl->cnode,
if ((res = spa_node_port_enum_params_sync(impl->cnode,
impl->direction, 0,
SPA_PARAM_EnumFormat, &state,
format, &format, &b)) <= 0) {
format, &format, &b)) != 1) {
debug_params(impl, impl->cnode, impl->direction, 0,
SPA_PARAM_EnumFormat, format);
return -ENOTSUP;
@ -524,22 +545,22 @@ static int negotiate_buffers(struct impl *impl)
return 0;
state = 0;
if ((res = spa_node_port_enum_params(impl->adapter_mix,
if ((res = spa_node_port_enum_params_sync(impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
SPA_PARAM_Buffers, &state,
param, &param, &b)) <= 0) {
param, &param, &b)) < 0) {
debug_params(impl, impl->adapter_mix,
SPA_DIRECTION_REVERSE(impl->direction),
impl->adapter_mix_port,
SPA_PARAM_Buffers, param);
return -ENOTSUP;
}
if (res == 0)
if (res != 1)
param = NULL;
state = 0;
if ((res = spa_node_port_enum_params(impl->cnode,
if ((res = spa_node_port_enum_params_sync(impl->cnode,
impl->direction, 0,
SPA_PARAM_Buffers, &state,
param, &param, &b)) < 0) {
@ -833,6 +854,7 @@ static const struct spa_node impl_node = {
SPA_VERSION_NODE,
.set_callbacks = impl_node_set_callbacks,
.sync = impl_node_sync,
.wait = impl_node_wait,
.enum_params = impl_node_enum_params,
.set_param = impl_node_set_param,
.set_io = impl_node_set_io,
@ -861,10 +883,7 @@ node_init(struct node *this,
this->log = support[i].data;
}
this->node = impl_node;
this->seq = 1;
return SPA_RESULT_RETURN_ASYNC(this->seq++);
return 0;
}
static int do_port_info(void *data, struct pw_port *port)
@ -957,10 +976,10 @@ static void client_node_initialized(void *data)
state = 0;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
if ((res = spa_node_port_enum_params(impl->cnode,
if ((res = spa_node_port_enum_params_sync(impl->cnode,
impl->direction, 0,
SPA_PARAM_EnumFormat, &state,
NULL, &format, &b)) <= 0) {
NULL, &format, &b)) != 1) {
pw_log_warn("client-stream %p: no format given", &impl->this);
impl->adapter = impl->cnode;
impl->adapter_mix = impl->client_port->mix;
@ -1049,15 +1068,6 @@ static void client_node_initialized(void *data)
items[0] = SPA_DICT_ITEM_INIT("media.class", media_class);
pw_node_update_properties(impl->this.node, &SPA_DICT_INIT(items, 1));
pw_node_register(impl->this.node,
pw_resource_get_client(impl->client_node->resource),
impl->client_node->parent,
NULL);
pw_log_debug("client-stream %p: activating", &impl->this);
pw_node_set_active(impl->this.node, true);
}
static void cleanup(struct impl *impl)
@ -1087,15 +1097,6 @@ static void client_node_destroy(void *data)
cleanup(impl);
}
static void client_node_async_complete(void *data, uint32_t seq, int res)
{
struct impl *impl = data;
struct node *node = &impl->node;
pw_log_debug("client-stream %p: async complete %d %d", &impl->this, seq, res);
node->callbacks->done(node->callbacks_data, seq);
}
static void client_node_active_changed(void *data, bool active)
{
struct impl *impl = data;
@ -1118,7 +1119,6 @@ static const struct pw_node_events client_node_events = {
PW_VERSION_NODE_EVENTS,
.destroy = client_node_destroy,
.initialized = client_node_initialized,
.async_complete = client_node_async_complete,
.active_changed = client_node_active_changed,
.info_changed = client_node_info_changed,
};
@ -1225,7 +1225,7 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
client,
parent,
name,
PW_SPA_NODE_FLAG_ASYNC,
PW_SPA_NODE_FLAG_ACTIVATE,
&impl->node.node,
NULL,
properties, 0);

View file

@ -61,7 +61,7 @@ client_node_marshal_update(void *object,
struct spa_pod_frame f;
uint32_t i;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_UPDATE, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -93,7 +93,7 @@ client_node_marshal_port_update(void *object,
struct spa_pod_frame f[2];
uint32_t i, n_items;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE, NULL);
spa_pod_builder_push_struct(b, &f[0]);
spa_pod_builder_add(b,
@ -134,7 +134,7 @@ static int client_node_marshal_set_active(void *object, bool active)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Bool(active));
@ -147,7 +147,7 @@ static int client_node_marshal_event_method(void *object, struct spa_event *even
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_EVENT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(event));
@ -472,7 +472,7 @@ client_node_marshal_add_mem(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(mem_id),
@ -488,7 +488,7 @@ static int client_node_marshal_transport(void *object, uint32_t node_id, int rea
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_TRANSPORT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(node_id),
@ -505,7 +505,7 @@ client_node_marshal_set_param(void *object, uint32_t id, uint32_t flags,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -520,7 +520,7 @@ static int client_node_marshal_event_event(void *object, const struct spa_event
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_EVENT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(event));
@ -534,7 +534,7 @@ client_node_marshal_command(void *object, const struct spa_command *command)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(command));
@ -551,7 +551,7 @@ client_node_marshal_add_port(void *object,
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -570,7 +570,7 @@ client_node_marshal_remove_port(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(direction),
@ -590,7 +590,7 @@ client_node_marshal_port_set_param(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(direction),
@ -614,7 +614,7 @@ client_node_marshal_port_use_buffers(void *object,
struct spa_pod_frame f;
uint32_t i, j;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_USE_BUFFERS, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -668,7 +668,7 @@ client_node_marshal_port_set_io(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(direction),
@ -693,7 +693,7 @@ client_node_marshal_set_activation(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_ACTIVATION, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(node_id),
@ -715,7 +715,7 @@ client_node_marshal_set_io(void *object,
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_IO, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
SPA_POD_Int(memid),

View file

@ -30,6 +30,7 @@
#include <sys/mman.h>
#include <spa/pod/parser.h>
#include <spa/node/utils.h>
#include <spa/debug/types.h>
#include "pipewire/pipewire.h"
@ -413,10 +414,10 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
struct spa_pod *param;
spa_pod_builder_init(&b, buf, sizeof(buf));
if (spa_node_port_enum_params(port->node->node,
if (spa_node_port_enum_params_sync(port->node->node,
port->direction, port->port_id,
SPA_PARAM_List, &idx1,
NULL, &param, &b) <= 0)
NULL, &param, &b) != 1)
break;
spa_pod_parse_object(param,
@ -424,18 +425,18 @@ static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_
SPA_PARAM_LIST_id, SPA_POD_Id(&id));
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
params[n_params++] = pw_spa_pod_copy(param);
params[n_params++] = spa_pod_copy(param);
for (idx2 = 0;;) {
spa_pod_builder_init(&b, buf, sizeof(buf));
if (spa_node_port_enum_params(port->node->node,
if (spa_node_port_enum_params_sync(port->node->node,
port->direction, port->port_id,
id, &idx2,
NULL, &param, &b) <= 0)
NULL, &param, &b) != 1)
break;
params = realloc(params, sizeof(struct spa_pod *) * (n_params + 1));
params[n_params++] = pw_spa_pod_copy(param);
params[n_params++] = spa_pod_copy(param);
}
}
}

View file

@ -754,10 +754,10 @@ const static struct pw_protocol_implementaton protocol_impl = {
};
static struct spa_pod_builder *
impl_ext_begin_proxy(struct pw_proxy *proxy, uint8_t opcode)
impl_ext_begin_proxy(struct pw_proxy *proxy, uint8_t opcode, int *res)
{
struct client *impl = SPA_CONTAINER_OF(proxy->remote->conn, struct client, this);
return pw_protocol_native_connection_begin_proxy(impl->connection, proxy, opcode);
return pw_protocol_native_connection_begin(impl->connection, proxy->id, opcode, res);
}
static uint32_t impl_ext_add_proxy_fd(struct pw_proxy *proxy, int fd)
@ -780,10 +780,10 @@ static int impl_ext_end_proxy(struct pw_proxy *proxy,
}
static struct spa_pod_builder *
impl_ext_begin_resource(struct pw_resource *resource, uint8_t opcode)
impl_ext_begin_resource(struct pw_resource *resource, uint8_t opcode, int *res)
{
struct client_data *data = resource->client->user_data;
return pw_protocol_native_connection_begin_resource(data->connection, resource, opcode);
return pw_protocol_native_connection_begin(data->connection, resource->id, opcode, res);
}
static uint32_t impl_ext_add_resource_fd(struct pw_resource *resource, int fd)
@ -803,7 +803,6 @@ static int impl_ext_end_resource(struct pw_resource *resource,
struct client_data *data = resource->client->user_data;
return pw_protocol_native_connection_end(data->connection, builder);
}
const static struct pw_protocol_native_ext protocol_ext_impl = {
PW_VERSION_PROTOCOL_NATIVE_EXT,
impl_ext_begin_proxy,

View file

@ -369,32 +369,17 @@ static const struct spa_pod_builder_callbacks builder_callbacks = {
};
struct spa_pod_builder *
pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connection *conn,
struct pw_resource *resource,
uint8_t opcode)
pw_protocol_native_connection_begin(struct pw_protocol_native_connection *conn,
uint32_t id, uint8_t opcode, int *res)
{
struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this);
impl->dest_id = resource->id;
impl->opcode = opcode;
impl->builder = SPA_POD_BUILDER_INIT(NULL, 0);
impl->builder.callbacks = &builder_callbacks;
impl->builder.callbacks_data = impl;
return &impl->builder;
}
struct spa_pod_builder *
pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *conn,
struct pw_proxy *proxy,
uint8_t opcode)
{
struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this);
impl->dest_id = proxy->id;
impl->dest_id = id;
impl->opcode = opcode;
impl->builder = SPA_POD_BUILDER_INIT(NULL, 0);
impl->builder.callbacks = &builder_callbacks;
impl->builder.callbacks_data = impl;
if (res)
*res = SPA_RESULT_RETURN_ASYNC(impl->seq);
return &impl->builder;
}

View file

@ -82,14 +82,9 @@ uint32_t pw_protocol_native_connection_add_fd(struct pw_protocol_native_connecti
int pw_protocol_native_connection_get_fd(struct pw_protocol_native_connection *conn, uint32_t index);
struct spa_pod_builder *
pw_protocol_native_connection_begin_resource(struct pw_protocol_native_connection *conn,
struct pw_resource *resource,
uint8_t opcode);
pw_protocol_native_connection_begin(struct pw_protocol_native_connection *conn,
uint32_t id, uint8_t opcode, int *res);
struct spa_pod_builder *
pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *conn,
struct pw_proxy *proxy,
uint8_t opcode);
int
pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn,
struct spa_pod_builder *builder);

View file

@ -37,7 +37,7 @@ static int core_method_marshal_hello(void *object, uint32_t version)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_HELLO);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_HELLO, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(version));
@ -49,12 +49,13 @@ static int core_method_marshal_sync(void *object, uint32_t id, uint32_t seq)
{
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
int res;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC, &res);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
SPA_POD_Int(seq));
SPA_POD_Int(res));
return pw_protocol_native_end_proxy(proxy, b);
}
@ -64,7 +65,7 @@ static int core_method_marshal_done(void *object, uint32_t id, uint32_t seq)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DONE);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DONE, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -78,7 +79,7 @@ static int core_method_marshal_error(void *object, uint32_t id, int res, const c
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_ERROR);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_ERROR, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -93,7 +94,7 @@ static int core_method_marshal_get_registry(void *object, uint32_t version, uint
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_GET_REGISTRY);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_GET_REGISTRY, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(version),
@ -128,7 +129,7 @@ core_method_marshal_create_object(void *object,
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_CREATE_OBJECT, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -149,7 +150,7 @@ core_method_marshal_destroy(void *object, uint32_t id)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DESTROY);
b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_DESTROY, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id));
@ -263,7 +264,7 @@ static int core_event_marshal_info(void *object, const struct pw_core_info *info
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -286,7 +287,7 @@ static int core_event_marshal_done(void *object, uint32_t id, uint32_t seq)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_DONE);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_DONE, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -299,12 +300,13 @@ static int core_event_marshal_sync(void *object, uint32_t id, uint32_t seq)
{
struct pw_resource *resource = object;
struct spa_pod_builder *b;
int res;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_SYNC);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_SYNC, &res);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
SPA_POD_Int(seq));
SPA_POD_Int(res));
return pw_protocol_native_end_resource(resource, b);
}
@ -314,7 +316,7 @@ static int core_event_marshal_error(void *object, uint32_t id, int res, const ch
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_ERROR);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_ERROR, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -329,7 +331,7 @@ static int core_event_marshal_remove_id(void *object, uint32_t id)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_REMOVE_ID);
b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_REMOVE_ID, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id));
@ -475,7 +477,7 @@ static int registry_marshal_global(void *object, uint32_t id, uint32_t parent_id
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL);
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -496,7 +498,7 @@ static int registry_marshal_global_remove(void *object, uint32_t id)
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE);
b = pw_protocol_native_begin_resource(resource, PW_REGISTRY_PROXY_EVENT_GLOBAL_REMOVE, NULL);
spa_pod_builder_add_struct(b, SPA_POD_Int(id));
@ -540,7 +542,7 @@ static int module_marshal_info(void *object, const struct pw_module_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_MODULE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_MODULE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -597,7 +599,7 @@ static int device_marshal_info(void *object, const struct pw_device_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -650,7 +652,7 @@ static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint3
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_DEVICE_PROXY_EVENT_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -685,7 +687,7 @@ static int device_marshal_enum_params(void *object, uint32_t id, uint32_t index,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS);
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_ENUM_PARAMS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -720,7 +722,7 @@ static int device_marshal_set_param(void *object, uint32_t id, uint32_t flags,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_SET_PARAM);
b = pw_protocol_native_begin_proxy(proxy, PW_DEVICE_PROXY_METHOD_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -752,7 +754,7 @@ static int factory_marshal_info(void *object, const struct pw_factory_info *info
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_FACTORY_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -809,7 +811,7 @@ static int node_marshal_info(void *object, const struct pw_node_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -874,7 +876,7 @@ static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_NODE_PROXY_EVENT_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -909,7 +911,7 @@ static int node_marshal_enum_params(void *object, uint32_t id, uint32_t index, u
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS);
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_ENUM_PARAMS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -944,7 +946,7 @@ static int node_marshal_set_param(void *object, uint32_t id, uint32_t flags,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SET_PARAM);
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SET_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -975,7 +977,7 @@ static int node_marshal_send_command(void *object, const struct spa_command *com
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SEND_COMMAND);
b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SEND_COMMAND, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Pod(command));
return pw_protocol_native_end_proxy(proxy, b);
@ -1001,7 +1003,7 @@ static int port_marshal_info(void *object, const struct pw_port_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -1054,7 +1056,7 @@ static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_
struct pw_resource *resource = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_PARAM);
b = pw_protocol_native_begin_resource(resource, PW_PORT_PROXY_EVENT_PARAM, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -1089,7 +1091,7 @@ static int port_marshal_enum_params(void *object, uint32_t id, uint32_t index, u
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS);
b = pw_protocol_native_begin_proxy(proxy, PW_PORT_PROXY_METHOD_ENUM_PARAMS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Id(id),
@ -1124,7 +1126,7 @@ static int client_marshal_info(void *object, const struct pw_client_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -1177,7 +1179,7 @@ static int client_marshal_permissions(void *object, uint32_t index, uint32_t n_p
struct spa_pod_frame f[2];
uint32_t i, n = 0;
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_PERMISSIONS);
b = pw_protocol_native_begin_resource(resource, PW_CLIENT_PROXY_EVENT_PERMISSIONS, NULL);
for (i = 0; i < n_permissions; i++) {
if (permissions[i].permissions != SPA_ID_INVALID)
@ -1235,7 +1237,7 @@ static int client_marshal_error(void *object, uint32_t id, int res, const char *
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_ERROR);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_ERROR, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
SPA_POD_Int(res),
@ -1265,7 +1267,7 @@ static int client_marshal_get_permissions(void *object, uint32_t index, uint32_t
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_GET_PERMISSIONS);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_GET_PERMISSIONS, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(index),
@ -1280,7 +1282,7 @@ static int client_marshal_update_properties(void *object, const struct spa_dict
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PROPERTIES);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PROPERTIES, NULL);
spa_pod_builder_push_struct(b, &f);
push_dict(b, props);
@ -1338,7 +1340,7 @@ static int client_marshal_update_permissions(void *object, uint32_t n_permission
struct spa_pod_frame f;
uint32_t i;
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS);
b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_PROXY_METHOD_UPDATE_PERMISSIONS, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_int(b, n_permissions);
@ -1382,7 +1384,7 @@ static int link_marshal_info(void *object, const struct pw_link_info *info)
struct spa_pod_builder *b;
struct spa_pod_frame f;
b = pw_protocol_native_begin_resource(resource, PW_LINK_PROXY_EVENT_INFO);
b = pw_protocol_native_begin_resource(resource, PW_LINK_PROXY_EVENT_INFO, NULL);
spa_pod_builder_push_struct(b, &f);
spa_pod_builder_add(b,
@ -1497,7 +1499,7 @@ static int registry_marshal_bind(void *object, uint32_t id,
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_BIND);
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_BIND, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id),
@ -1513,7 +1515,7 @@ static int registry_marshal_destroy(void *object, uint32_t id)
struct pw_proxy *proxy = object;
struct spa_pod_builder *b;
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY);
b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY, NULL);
spa_pod_builder_add_struct(b,
SPA_POD_Int(id));
return pw_protocol_native_end_proxy(proxy, b);

View file

@ -31,6 +31,7 @@
#include <dlfcn.h>
#include <spa/node/node.h>
#include <spa/node/utils.h>
#include <spa/param/props.h>
#include <spa/pod/iter.h>
#include <spa/debug/types.h>
@ -48,7 +49,6 @@ struct impl {
struct pw_global *parent;
enum pw_spa_node_flags flags;
bool async_init;
void *hnd;
struct spa_handle *handle;
@ -57,8 +57,11 @@ struct impl {
char *factory_name;
struct spa_hook node_listener;
struct spa_pending init_pending;
void *user_data;
int async_init:1;
};
static void pw_spa_node_free(void *data)
@ -79,7 +82,7 @@ static void pw_spa_node_free(void *data)
dlclose(impl->hnd);
}
static void complete_init(struct impl *impl)
static int complete_init(struct impl *impl)
{
struct pw_node *this = impl->this;
@ -93,24 +96,20 @@ static void complete_init(struct impl *impl)
pw_node_register(this, impl->owner, impl->parent, NULL);
else
pw_node_initialized(this);
return 0;
}
static void on_node_done(void *data, uint32_t seq, int res)
static int on_init_done(void *data, int seq, int res, const void *result)
{
struct impl *impl = data;
struct pw_node *this = impl->this;
if (impl->async_init) {
complete_init(impl);
impl->async_init = false;
}
pw_log_debug("spa-node %p: async complete event %d %d", this, seq, res);
pw_log_debug("spa-node %p: init complete event %d %d", this, seq, res);
return complete_init(impl);
}
static const struct pw_node_events node_events = {
PW_VERSION_NODE_EVENTS,
.free = pw_spa_node_free,
.async_complete = on_node_done,
};
struct pw_node *
@ -126,6 +125,7 @@ pw_spa_node_new(struct pw_core *core,
{
struct pw_node *this;
struct impl *impl;
int res;
this = pw_node_new(core, name, properties, sizeof(struct impl) + user_data_size);
if (this == NULL)
@ -137,18 +137,27 @@ pw_spa_node_new(struct pw_core *core,
impl->parent = parent;
impl->node = node;
impl->flags = flags;
impl->async_init = flags & PW_SPA_NODE_FLAG_ASYNC;
if (user_data_size > 0)
impl->user_data = SPA_MEMBER(impl, sizeof(struct impl), void);
pw_node_add_listener(this, &impl->node_listener, &node_events, impl);
pw_node_set_implementation(this, impl->node);
res = pw_node_set_implementation(this, impl->node);
if (!impl->async_init)
if (res < 0)
goto clean_node;
if (SPA_RESULT_IS_ASYNC(res)) {
spa_node_wait(impl->node, res, &impl->init_pending, on_init_done, impl);
} else {
complete_init(impl);
}
return this;
clean_node:
pw_node_destroy(this);
return NULL;
}
void *pw_spa_node_get_user_data(struct pw_node *node)
@ -169,7 +178,8 @@ setup_props(struct pw_core *core, struct spa_node *spa_node, struct pw_propertie
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buf, sizeof(buf));
const struct spa_pod_prop *prop = NULL;
if ((res = spa_node_enum_params(spa_node, SPA_PARAM_Props, &index, NULL, &props, &b)) <= 0) {
if ((res = spa_node_enum_params_sync(spa_node,
SPA_PARAM_Props, &index, NULL, &props, &b)) != 1) {
pw_log_debug("spa_node_get_props failed: %d", res);
return res;
}
@ -290,8 +300,6 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
pw_log_error("can't make factory instance: %d", res);
goto init_failed;
}
if (SPA_RESULT_IS_ASYNC(res))
flags |= PW_SPA_NODE_FLAG_ASYNC;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0) {
pw_log_error("can't get node interface %d", res);

View file

@ -35,10 +35,9 @@ extern "C" {
#endif
enum pw_spa_node_flags {
PW_SPA_NODE_FLAG_ASYNC = (1 << 0),
PW_SPA_NODE_FLAG_DISABLE = (1 << 1),
PW_SPA_NODE_FLAG_ACTIVATE = (1 << 2),
PW_SPA_NODE_FLAG_NO_REGISTER = (1 << 3),
PW_SPA_NODE_FLAG_DISABLE = (1 << 0),
PW_SPA_NODE_FLAG_ACTIVATE = (1 << 1),
PW_SPA_NODE_FLAG_NO_REGISTER = (1 << 2),
};
struct pw_node *