From eea062ee536b0813dd0d4225b5fc01127fcc0c4c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 18 Feb 2019 12:31:36 +0100 Subject: [PATCH] interfaces: improve remote API Add return values to events and method callbacks. This makes it possible to pass any error or async return value. Add sync/done/error in both directions so that both proxy and resource and perform/reply sync and produce errors. Return a SPA_ASYNC from remote method calls (and events), keep the sequence number in the connection. With the core sync/done we can remove the client-node done method and it's internal sequence number along with the seq number in method calls. We can also use the method/event async return value to perform a sync with as the unique sequence number for this method. Add sync method and done/error event to proxy and resource. --- pipewire-jack | 2 +- pipewire-pulseaudio | 2 +- spa/examples/example-control.c | 18 +- spa/examples/local-v4l2.c | 29 +- spa/include/spa/monitor/device.h | 8 +- spa/include/spa/monitor/monitor.h | 4 +- spa/include/spa/node/node.h | 77 ++-- spa/plugins/alsa/alsa-sink.c | 17 +- spa/plugins/audioconvert/audioconvert.c | 10 +- spa/tools/spa-inspect.c | 6 +- spa/tools/spa-monitor.c | 6 +- src/examples/media-session.c | 52 ++- src/extensions/client-node.h | 98 ++--- src/extensions/protocol-native.h | 8 +- src/gst/gstpipewiredeviceprovider.c | 41 +- src/modules/module-client-node/client-node.c | 109 ++--- .../module-client-node/client-stream.c | 25 +- .../module-client-node/protocol-native.c | 149 +++---- src/modules/module-client-node/remote-node.c | 146 ++++--- src/modules/module-protocol-native.c | 11 +- .../module-protocol-native/connection.c | 13 +- .../module-protocol-native/connection.h | 2 +- .../module-protocol-native/protocol-native.c | 400 ++++++++++-------- src/modules/spa/spa-monitor.c | 3 +- src/pipewire/client.c | 17 +- src/pipewire/core.c | 95 +++-- src/pipewire/device.c | 12 +- src/pipewire/interfaces.h | 265 ++++++++---- src/pipewire/link.c | 21 +- src/pipewire/node.c | 54 ++- src/pipewire/port.c | 3 +- src/pipewire/private.h | 3 + src/pipewire/proxy.c | 22 + src/pipewire/proxy.h | 10 + src/pipewire/remote.c | 27 +- src/pipewire/resource.c | 17 +- src/pipewire/resource.h | 12 +- src/pipewire/stream.c | 16 + src/tests/test-interfaces.c | 76 ++-- src/tools/pipewire-cli.c | 55 ++- src/tools/pipewire-monitor.c | 56 ++- 41 files changed, 1180 insertions(+), 817 deletions(-) diff --git a/pipewire-jack b/pipewire-jack index 1108c5d83..af96643ea 160000 --- a/pipewire-jack +++ b/pipewire-jack @@ -1 +1 @@ -Subproject commit 1108c5d83d2f105f6976a6edd79efa348b688d23 +Subproject commit af96643eaa5d3d9df727629e96a0b1f101a16664 diff --git a/pipewire-pulseaudio b/pipewire-pulseaudio index 5f9200d9e..61edd78bf 160000 --- a/pipewire-pulseaudio +++ b/pipewire-pulseaudio @@ -1 +1 @@ -Subproject commit 5f9200d9ee58271e60ff24e91e07fa340d71d494 +Subproject commit 61edd78bf4a3bba5edab0ba0c10a7d7f12ff3f7a diff --git a/spa/examples/example-control.c b/spa/examples/example-control.c index ba0a07426..b083b46e8 100644 --- a/spa/examples/example-control.c +++ b/spa/examples/example-control.c @@ -184,16 +184,6 @@ static int make_node(struct data *data, struct spa_node **node, const char *lib, return -EBADF; } -static void on_sink_done(void *data, int seq, int res) -{ - printf("got done %d %d\n", seq, res); -} - -static void on_sink_event(void *data, struct spa_event *event) -{ - printf("got event %d\n", SPA_EVENT_TYPE(event)); -} - static void update_props(struct data *data) { struct spa_pod_builder b; @@ -233,7 +223,7 @@ static void update_props(struct data *data) data->volume_accum -= M_PI_M2; } -static void on_sink_ready(void *_data, int status) +static int on_sink_ready(void *_data, int status) { struct data *data = _data; @@ -241,20 +231,20 @@ static void on_sink_ready(void *_data, int status) spa_graph_node_process(&data->source_node); spa_graph_node_process(&data->sink_node); + return 0; } -static void +static int on_sink_reuse_buffer(void *_data, uint32_t port_id, uint32_t buffer_id) { struct data *data = _data; data->source_sink_io[0].buffer_id = buffer_id; + return 0; } static const struct spa_node_callbacks sink_callbacks = { SPA_VERSION_NODE_CALLBACKS, - .done = on_sink_done, - .event = on_sink_event, .ready = on_sink_ready, .reuse_buffer = on_sink_reuse_buffer }; diff --git a/spa/examples/local-v4l2.c b/spa/examples/local-v4l2.c index 98eca7aae..1abe13fb5 100644 --- a/spa/examples/local-v4l2.c +++ b/spa/examples/local-v4l2.c @@ -145,21 +145,7 @@ static void handle_events(struct data *data) } } -static void on_source_done(void *data, int seq, int res) -{ - printf("got done %d %d\n", seq, res); -} - -static void on_source_event(void *_data, struct spa_event *event) -{ - struct data *data = _data; - - handle_events(data); - - printf("got event %d\n", SPA_EVENT_TYPE(event)); -} - -static void on_source_ready(void *_data, int status) +static int on_source_ready(void *_data, int status) { struct data *data = _data; int res; @@ -177,7 +163,7 @@ static void on_source_ready(void *_data, int status) printf("got process error %d\n", res); if (io->buffer_id > MAX_BUFFERS) - return; + return -EINVAL; b = &data->buffers[io->buffer_id]; @@ -194,26 +180,28 @@ static void on_source_ready(void *_data, int status) if (SDL_LockTexture(texture, NULL, &sdata, &sstride) < 0) { fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError()); - return; + return -EIO; } } else { uint8_t *map; if (SDL_LockTexture(data->texture, NULL, &ddata, &dstride) < 0) { fprintf(stderr, "Couldn't lock texture: %s\n", SDL_GetError()); - return; + return -EIO; } sdata = datas[0].data; if (datas[0].type == SPA_DATA_MemFd || datas[0].type == SPA_DATA_DmaBuf) { map = mmap(NULL, datas[0].maxsize + datas[0].mapoffset, PROT_READ, MAP_PRIVATE, datas[0].fd, 0); + if (map == MAP_FAILED) + return -errno; sdata = SPA_MEMBER(map, datas[0].mapoffset, uint8_t); } else if (datas[0].type == SPA_DATA_MemPtr) { map = NULL; sdata = datas[0].data; } else - return; + return -EIO; sstride = datas[0].chunk->stride; @@ -233,12 +221,11 @@ static void on_source_ready(void *_data, int status) } io->status = SPA_STATUS_NEED_BUFFER; + return 0; } static const struct spa_node_callbacks source_callbacks = { SPA_VERSION_NODE_CALLBACKS, - .done = on_source_done, - .event = on_source_event, .ready = on_source_ready }; diff --git a/spa/include/spa/monitor/device.h b/spa/include/spa/monitor/device.h index 025e9cacd..77ddce100 100644 --- a/spa/include/spa/monitor/device.h +++ b/spa/include/spa/monitor/device.h @@ -74,15 +74,15 @@ struct spa_device_callbacks { uint32_t version; /** notify extra information about the device */ - void (*info) (void *data, const struct spa_device_info *info); + int (*info) (void *data, const struct spa_device_info *info); /** a device event */ - void (*event) (void *data, struct spa_event *event); + int (*event) (void *data, struct spa_event *event); /** info changed for an object managed by the device, info is NULL when * the object is removed */ - void (*object_info) (void *data, uint32_t id, - const struct spa_device_object_info *info); + int (*object_info) (void *data, uint32_t id, + const struct spa_device_object_info *info); }; /** diff --git a/spa/include/spa/monitor/monitor.h b/spa/include/spa/monitor/monitor.h index fcd475b1d..bbf244c01 100644 --- a/spa/include/spa/monitor/monitor.h +++ b/spa/include/spa/monitor/monitor.h @@ -80,10 +80,10 @@ struct spa_monitor_callbacks { uint32_t version; /** receive extra information about the monitor */ - void (*info) (void *data, const struct spa_dict *info); + int (*info) (void *data, const struct spa_dict *info); /** an item is added/removed/changed on the monitor */ - void (*event) (void *data, struct spa_event *event); + int (*event) (void *data, struct spa_event *event); }; /** diff --git a/spa/include/spa/node/node.h b/spa/include/spa/node/node.h index be1bd9d9d..cfa6d4ce1 100644 --- a/spa/include/spa/node/node.h +++ b/spa/include/spa/node/node.h @@ -97,18 +97,22 @@ struct spa_node_callbacks { #define SPA_VERSION_NODE_CALLBACKS 0 uint32_t version; /**< version of this structure */ - /** Emited when info changes */ - void (*info) (void *data, const struct spa_node_info *info); - - /** Emited when port info changes, NULL when port is removed */ - void (*port_info) (void *data, - enum spa_direction direction, uint32_t port, - const struct spa_port_info *info); - - /** Emited when an async operation completed. + /** Emited as a reply to a sync method with \a seq. * * Will be called from the main thread. */ - void (*done) (void *data, int seq, int res); + int (*done) (void *data, uint32_t seq); + + /** an asynchronous error occured */ + int (*error) (void *data, int res, const char *message); + + /** Emited when info changes */ + int (*info) (void *data, const struct spa_node_info *info); + + /** Emited when port info changes, NULL when port is removed */ + int (*port_info) (void *data, + enum spa_direction direction, uint32_t port, + const struct spa_port_info *info); + /** * \param node a spa_node * \param event the event that was emited @@ -116,7 +120,7 @@ struct spa_node_callbacks { * This will be called when an out-of-bound event is notified * on \a node. The callback will be called from the main thread. */ - void (*event) (void *data, struct spa_event *event); + int (*event) (void *data, struct spa_event *event); /** * \param node a spa_node @@ -127,7 +131,7 @@ struct spa_node_callbacks { * When this function is NULL, synchronous operation is requested * on the ports. */ - void (*ready) (void *data, int state); + int (*ready) (void *data, int state); /** * \param node a spa_node @@ -140,9 +144,9 @@ struct spa_node_callbacks { * When this function is NULL, the buffers to reuse will be set in * the io area of the input ports. */ - void (*reuse_buffer) (void *data, - uint32_t port_id, - uint32_t buffer_id); + int (*reuse_buffer) (void *data, + uint32_t port_id, + uint32_t buffer_id); }; @@ -160,6 +164,32 @@ struct spa_node { * structure in the future */ #define SPA_VERSION_NODE 0 uint32_t version; + + /** + * Set callbacks to receive events and scheduling callbacks from \a node. + * if \a callbacks is NULL, the current callbacks are removed. + * + * This function must be called from the main thread. + * + * \param node a spa_node + * \param callbacks callbacks to set + * \return 0 on success + * -EINVAL when node is NULL + */ + int (*set_callbacks) (struct spa_node *node, + const struct spa_node_callbacks *callbacks, + void *data); + /** + * Perform a sync operation. + * + * Calling this method will emit the done event or -EIO when + * no callbacks are installed. + * + * Because all methods are serialized in the node, this can be used + * to wait for completion of all previous method calls. + */ + int (*sync) (struct spa_node *node, uint32_t seq); + /** * Enumerate the parameters of a node. * @@ -251,20 +281,6 @@ struct spa_node { */ int (*send_command) (struct spa_node *node, const struct spa_command *command); - /** - * Set callbacks to receive events and scheduling callbacks from \a node. - * if \a callbacks is NULL, the current callbacks are removed. - * - * This function must be called from the main thread. - * - * \param node a spa_node - * \param callbacks callbacks to set - * \return 0 on success - * -EINVAL when node is NULL - */ - int (*set_callbacks) (struct spa_node *node, - const struct spa_node_callbacks *callbacks, - void *data); /** * Make a new port with \a port_id. The caller should use get_port_ids() to * find an unused id for the given \a direction. @@ -477,11 +493,12 @@ struct spa_node { int (*process) (struct spa_node *node); }; +#define spa_node_set_callbacks(n,...) (n)->set_callbacks((n),__VA_ARGS__) +#define spa_node_sync(n,...) (n)->sync((n),__VA_ARGS__) #define spa_node_enum_params(n,...) (n)->enum_params((n),__VA_ARGS__) #define spa_node_set_param(n,...) (n)->set_param((n),__VA_ARGS__) #define spa_node_set_io(n,...) (n)->set_io((n),__VA_ARGS__) #define spa_node_send_command(n,...) (n)->send_command((n),__VA_ARGS__) -#define spa_node_set_callbacks(n,...) (n)->set_callbacks((n),__VA_ARGS__) #define spa_node_add_port(n,...) (n)->add_port((n),__VA_ARGS__) #define spa_node_remove_port(n,...) (n)->remove_port((n),__VA_ARGS__) #define spa_node_port_enum_params(n,...) (n)->port_enum_params((n),__VA_ARGS__) diff --git a/spa/plugins/alsa/alsa-sink.c b/spa/plugins/alsa/alsa-sink.c index 6d5d8fcfa..b188ba716 100644 --- a/spa/plugins/alsa/alsa-sink.c +++ b/spa/plugins/alsa/alsa-sink.c @@ -264,6 +264,20 @@ static void emit_port_info(struct state *this) } } +static int +impl_node_sync(struct spa_node *node, uint32_t seq) +{ + struct state *this; + + spa_return_val_if_fail(node != NULL, -EINVAL); + this = SPA_CONTAINER_OF(node, struct state, node); + + spa_return_val_if_fail(this->callbacks && this->callbacks->done, -EIO); + + this->callbacks->done(this->callbacks_data, seq); + return 0; +} + static int impl_node_set_callbacks(struct spa_node *node, const struct spa_node_callbacks *callbacks, @@ -637,11 +651,12 @@ static int impl_node_process(struct spa_node *node) static const struct spa_node impl_node = { SPA_VERSION_NODE, + .set_callbacks = impl_node_set_callbacks, + .sync = impl_node_sync, .enum_params = impl_node_enum_params, .set_param = impl_node_set_param, .set_io = impl_node_set_io, .send_command = impl_node_send_command, - .set_callbacks = impl_node_set_callbacks, .add_port = impl_node_add_port, .remove_port = impl_node_remove_port, .port_enum_params = impl_node_port_enum_params, diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index ab18d5feb..1ed425ebd 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -550,16 +550,17 @@ static void emit_port_info(struct impl *this, } -static void fmt_input_port_info(void *data, +static int fmt_input_port_info(void *data, enum spa_direction direction, uint32_t port, const struct spa_port_info *info) { struct impl *this = data; if (direction != SPA_DIRECTION_INPUT) - return; + return 0; emit_port_info(this, direction, port, info); + return 0; } static struct spa_node_callbacks fmt_input_callbacks = { @@ -567,16 +568,17 @@ static struct spa_node_callbacks fmt_input_callbacks = { .port_info = fmt_input_port_info }; -static void fmt_output_port_info(void *data, +static int fmt_output_port_info(void *data, enum spa_direction direction, uint32_t port, const struct spa_port_info *info) { struct impl *this = data; if (direction != SPA_DIRECTION_OUTPUT) - return; + return 0; emit_port_info(this, direction, port, info); + return 0; } static struct spa_node_callbacks fmt_output_callbacks = { diff --git a/spa/tools/spa-inspect.c b/spa/tools/spa-inspect.c index 0520bfeb3..092de015f 100644 --- a/spa/tools/spa-inspect.c +++ b/spa/tools/spa-inspect.c @@ -136,7 +136,7 @@ inspect_port_params(struct data *data, struct spa_node *node, } } -static void node_info(void *_data, const struct spa_node_info *info) +static int node_info(void *_data, const struct spa_node_info *info) { struct data *data = _data; @@ -148,9 +148,10 @@ static void node_info(void *_data, const struct spa_node_info *info) spa_debug_dict(2, info->props); } inspect_node_params(data, data->node); + return 0; } -static void node_port_info(void *_data, enum spa_direction direction, uint32_t id, +static int node_port_info(void *_data, enum spa_direction direction, uint32_t id, const struct spa_port_info *info) { struct data *data = _data; @@ -164,6 +165,7 @@ static void node_port_info(void *_data, enum spa_direction direction, uint32_t i id); inspect_port_params(data, data->node, direction, id); } + return 0; } static const struct spa_node_callbacks node_callbacks = diff --git a/spa/tools/spa-monitor.c b/spa/tools/spa-monitor.c index 9786cb223..ccca863d5 100644 --- a/spa/tools/spa-monitor.c +++ b/spa/tools/spa-monitor.c @@ -61,12 +61,13 @@ static void inspect_item(struct data *data, struct spa_pod *item) spa_debug_pod(0, NULL, item); } -static void on_monitor_info(void *_data, const struct spa_dict *info) +static int on_monitor_info(void *_data, const struct spa_dict *info) { spa_debug_dict(0, info); + return 0; } -static void on_monitor_event(void *_data, struct spa_event *event) +static int on_monitor_event(void *_data, struct spa_event *event) { struct data *data = _data; @@ -84,6 +85,7 @@ static void on_monitor_event(void *_data, struct spa_event *event) inspect_item(data, SPA_POD_CONTENTS(struct spa_event, event)); break; } + return 0; } static int do_add_source(struct spa_loop *loop, struct spa_source *source) diff --git a/src/examples/media-session.c b/src/examples/media-session.c index 8cd38500a..8b0526f34 100644 --- a/src/examples/media-session.c +++ b/src/examples/media-session.c @@ -193,7 +193,7 @@ static void *find_object(struct impl *impl, uint32_t id) static void schedule_rescan(struct impl *impl) { if (impl->core_proxy) - pw_core_proxy_sync(impl->core_proxy, ++impl->seq); + pw_core_proxy_sync(impl->core_proxy, 0, ++impl->seq); } static void remove_idle_timeout(struct session *sess) @@ -344,7 +344,7 @@ static int on_node_running(struct impl *impl, struct node *node) return 0; } -static void node_event_info(void *object, const struct pw_node_info *info) +static int node_event_info(void *object, const struct pw_node_info *info) { struct node *n = object; struct impl *impl = n->obj.impl; @@ -364,10 +364,10 @@ static void node_event_info(void *object, const struct pw_node_info *info) default: break; } - + return 0; } -static void node_event_param(void *object, +static int node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { @@ -385,7 +385,7 @@ static void node_event_param(void *object, if (n->media_type != SPA_MEDIA_TYPE_audio || n->media_subtype != SPA_MEDIA_SUBTYPE_raw) - return; + return 0; spa_pod_object_fixate((struct spa_pod_object*)param); @@ -393,12 +393,12 @@ static void node_event_param(void *object, goto error; n->format = info; - return; + return 0; error: pw_log_warn("unhandled param:"); spa_debug_pod(2, NULL, param); - return; + return -EINVAL; } static const struct pw_node_proxy_events node_events = { @@ -579,14 +579,15 @@ handle_node(struct impl *impl, uint32_t id, uint32_t parent_id, return 1; } -static void port_event_info(void *object, const struct pw_port_info *info) +static int port_event_info(void *object, const struct pw_port_info *info) { struct port *p = object; pw_log_debug(NAME" %p: info for port %d", p->obj.impl, p->obj.id); p->info = pw_port_info_update(p->info, info); + return 0; } -static void port_event_param(void *object, +static int port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { @@ -597,28 +598,29 @@ static void port_event_param(void *object, pw_log_debug(NAME" %p: param for port %d", p->obj.impl, p->obj.id); if (node == NULL) - return; + return 0; if (id != SPA_PARAM_EnumFormat) - return; + return 0; if (node->manager) node->manager->enabled = true; if (spa_format_parse(param, &node->media_type, &node->media_subtype) < 0) - return; + return 0; if (node->media_type != SPA_MEDIA_TYPE_audio || node->media_subtype != SPA_MEDIA_SUBTYPE_raw) - return; + return 0; spa_pod_fixate((struct spa_pod*)param); if (spa_format_audio_raw_parse(param, &info) < 0) - return; + return -EINVAL; if (info.channels > node->format.channels) node->format = info; + return 0; } static const struct pw_port_proxy_events port_events = { @@ -697,7 +699,7 @@ handle_port(struct impl *impl, uint32_t id, uint32_t parent_id, uint32_t type, return 0; } -static void client_event_info(void *object, const struct pw_client_info *info) +static int client_event_info(void *object, const struct pw_client_info *info) { struct client *c = object; uint32_t i; @@ -708,7 +710,7 @@ static void client_event_info(void *object, const struct pw_client_info *info) pw_log_debug(NAME" %p: %s = %s", c, info->props->items[i].key, info->props->items[i].value); - + return 0; } static const struct pw_client_proxy_events client_events = { @@ -772,7 +774,7 @@ handle_client(struct impl *impl, uint32_t id, uint32_t parent_id, return 0; } -static void +static int registry_global(void *data,uint32_t id, uint32_t parent_id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props) @@ -804,9 +806,11 @@ registry_global(void *data,uint32_t id, uint32_t parent_id, } else schedule_rescan(impl); + + return res; } -static void +static int registry_global_remove(void *data, uint32_t id) { struct impl *impl = data; @@ -815,7 +819,7 @@ registry_global_remove(void *data, uint32_t id) pw_log_debug(NAME " %p: remove global '%d'", impl, id); if ((obj = find_object(impl, id)) == NULL) - return; + return 0; switch (obj->type) { case PW_TYPE_INTERFACE_Node: @@ -825,13 +829,13 @@ registry_global_remove(void *data, uint32_t id) remove_session(impl, node->manager); node->manager = NULL; break; - } default: break; } remove_object(impl, obj); schedule_rescan(impl); + return 0; } static const struct pw_registry_proxy_events registry_events = { @@ -1196,13 +1200,13 @@ do_link: return 1; } -static void dsp_node_event_info(void *object, const struct pw_node_info *info) +static int dsp_node_event_info(void *object, const struct pw_node_info *info) { struct session *s = object; struct node *dsp; if ((dsp = find_object(s->impl, info->id)) == NULL) - return; + return 0; pw_log_debug(NAME" %p: dsp node session %d id %d", dsp->obj.impl, s->id, info->id); @@ -1217,6 +1221,7 @@ static void dsp_node_event_info(void *object, const struct pw_node_info *info) dsp->format = s->node->format; dsp->profile_format = dsp->format; dsp->profile_format.format = SPA_AUDIO_FORMAT_F32P; + return 0; } static const struct pw_node_proxy_events dsp_node_events = { @@ -1292,11 +1297,12 @@ static void do_rescan(struct impl *impl) rescan_node(impl, node); } -static void core_done(void *data, uint32_t seq) +static int core_done(void *data, uint32_t id, uint32_t seq) { struct impl *impl = data; if (impl->seq == seq) do_rescan(impl); + return 0; } static const struct pw_core_proxy_events core_events = { diff --git a/src/extensions/client-node.h b/src/extensions/client-node.h index b44e2d3eb..ab82ad6b8 100644 --- a/src/extensions/client-node.h +++ b/src/extensions/client-node.h @@ -48,21 +48,17 @@ struct pw_client_node_buffer { struct spa_buffer *buffer; /**< buffer describing metadata and buffer memory */ }; -#define PW_CLIENT_NODE_PROXY_METHOD_DONE 0 -#define PW_CLIENT_NODE_PROXY_METHOD_UPDATE 1 -#define PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE 2 -#define PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE 3 -#define PW_CLIENT_NODE_PROXY_METHOD_EVENT 4 -#define PW_CLIENT_NODE_PROXY_METHOD_NUM 5 +#define PW_CLIENT_NODE_PROXY_METHOD_UPDATE 0 +#define PW_CLIENT_NODE_PROXY_METHOD_PORT_UPDATE 1 +#define PW_CLIENT_NODE_PROXY_METHOD_SET_ACTIVE 2 +#define PW_CLIENT_NODE_PROXY_METHOD_EVENT 3 +#define PW_CLIENT_NODE_PROXY_METHOD_NUM 4 /** \ref pw_client_node methods */ struct pw_client_node_proxy_methods { #define PW_VERSION_CLIENT_NODE_PROXY_METHODS 0 uint32_t version; - /** Complete an async operation */ - void (*done) (void *object, int seq, int res); - /** * Update the node ports and properties * @@ -73,7 +69,7 @@ struct pw_client_node_proxy_methods { * \param max_output_ports new max output ports * \param params new params */ - void (*update) (void *object, + int (*update) (void *object, #define PW_CLIENT_NODE_UPDATE_MAX_INPUTS (1 << 0) #define PW_CLIENT_NODE_UPDATE_MAX_OUTPUTS (1 << 1) #define PW_CLIENT_NODE_UPDATE_PARAMS (1 << 2) @@ -96,7 +92,7 @@ struct pw_client_node_proxy_methods { * \param params array of port parameters * \param info port information */ - void (*port_update) (void *object, + int (*port_update) (void *object, enum spa_direction direction, uint32_t port_id, #define PW_CLIENT_NODE_PORT_UPDATE_PARAMS (1 << 0) @@ -108,21 +104,15 @@ struct pw_client_node_proxy_methods { /** * Activate or deactivate the node */ - void (*set_active) (void *object, bool active); + int (*set_active) (void *object, bool active); /** * Send an event to the node * \param event the event to send */ - void (*event) (void *object, struct spa_event *event); + int (*event) (void *object, struct spa_event *event); }; -static inline void -pw_client_node_proxy_done(struct pw_client_node_proxy *p, int seq, int res) -{ - pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, done, seq, res); -} - -static inline void +static inline int pw_client_node_proxy_update(struct pw_client_node_proxy *p, uint32_t change_mask, uint32_t max_input_ports, @@ -131,13 +121,13 @@ pw_client_node_proxy_update(struct pw_client_node_proxy *p, const struct spa_pod **params, const struct spa_dict *props) { - pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, update, change_mask, + return pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, update, change_mask, max_input_ports, max_output_ports, n_params, params, props); } -static inline void +static inline int pw_client_node_proxy_port_update(struct pw_client_node_proxy *p, enum spa_direction direction, uint32_t port_id, @@ -146,7 +136,7 @@ pw_client_node_proxy_port_update(struct pw_client_node_proxy *p, const struct spa_pod **params, const struct spa_port_info *info) { - pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, port_update, direction, + return pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, port_update, direction, port_id, change_mask, n_params, @@ -154,16 +144,16 @@ pw_client_node_proxy_port_update(struct pw_client_node_proxy *p, info); } -static inline void +static inline int pw_client_node_proxy_set_active(struct pw_client_node_proxy *p, bool active) { - pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, set_active, active); + return pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, set_active, active); } -static inline void +static inline int pw_client_node_proxy_event(struct pw_client_node_proxy *p, struct spa_event *event) { - pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, event, event); + return pw_proxy_do((struct pw_proxy*)p, struct pw_client_node_proxy_methods, event, event); } #define PW_CLIENT_NODE_PROXY_EVENT_ADD_MEM 0 @@ -201,11 +191,11 @@ struct pw_client_node_proxy_events { * \param memfd the fd of the memory * \param flags flags for the \a memfd */ - void (*add_mem) (void *object, - uint32_t mem_id, - uint32_t type, - int memfd, - uint32_t flags); + int (*add_mem) (void *object, + uint32_t mem_id, + uint32_t type, + int memfd, + uint32_t flags); /** * Notify of a new transport area * @@ -215,24 +205,23 @@ struct pw_client_node_proxy_events { * \param readfd fd for signal data can be read * \param writefd fd for signal data can be written */ - void (*transport) (void *object, - uint32_t node_id, - int readfd, - int writefd); + int (*transport) (void *object, + uint32_t node_id, + int readfd, + int writefd); /** * Notify of a property change * * When the server configures the properties on the node * this event is sent * - * \param seq a sequence number * \param id the id of the parameter * \param flags parameter flags * \param param the param to set */ - void (*set_param) (void *object, uint32_t seq, - uint32_t id, uint32_t flags, - const struct spa_pod *param); + int (*set_param) (void *object, + uint32_t id, uint32_t flags, + const struct spa_pod *param); /** * Configure an IO area for the client * @@ -244,7 +233,7 @@ struct pw_client_node_proxy_events { * \param offset offset of io area in memory * \param size size of the io area */ - void (*set_io) (void *object, + int (*set_io) (void *object, uint32_t id, uint32_t mem_id, uint32_t offset, @@ -252,51 +241,44 @@ struct pw_client_node_proxy_events { /** * Receive an event from the client node * \param event the received event */ - void (*event) (void *object, const struct spa_event *event); + int (*event) (void *object, const struct spa_event *event); /** * Notify of a new node command * - * \param seq a sequence number * \param command the command */ - void (*command) (void *object, uint32_t seq, const struct spa_command *command); + int (*command) (void *object, const struct spa_command *command); /** * A new port was added to the node * * The server can at any time add a port to the node when there * are free ports available. * - * \param seq a sequence number * \param direction the direction of the port * \param port_id the new port id */ - void (*add_port) (void *object, - uint32_t seq, + int (*add_port) (void *object, enum spa_direction direction, uint32_t port_id); /** * A port was removed from the node * - * \param seq a sequence number * \param direction a port direction * \param port_id the remove port id */ - void (*remove_port) (void *object, - uint32_t seq, + int (*remove_port) (void *object, enum spa_direction direction, uint32_t port_id); /** * A parameter was configured on the port * - * \param seq a sequence number * \param direction a port direction * \param port_id the port id * \param id the id of the parameter * \param flags flags used when setting the param * \param param the new param */ - void (*port_set_param) (void *object, - uint32_t seq, + int (*port_set_param) (void *object, enum spa_direction direction, uint32_t port_id, uint32_t id, uint32_t flags, @@ -304,15 +286,13 @@ struct pw_client_node_proxy_events { /** * Notify the port of buffers * - * \param seq a sequence number * \param direction a port direction * \param port_id the port id * \param mix_id the mixer port id * \param n_buffer the number of buffers * \param buffers and array of buffer descriptions */ - void (*port_use_buffers) (void *object, - uint32_t seq, + int (*port_use_buffers) (void *object, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -321,7 +301,6 @@ struct pw_client_node_proxy_events { /** * Configure the io area with \a id of \a port_id. * - * \param seq a sequence number * \param direction the direction of the port * \param port_id the port id * \param mix_id the mixer port id @@ -330,8 +309,7 @@ struct pw_client_node_proxy_events { * \param offset offset of io area in memory * \param size size of the io area */ - void (*port_set_io) (void *object, - uint32_t seq, + int (*port_set_io) (void *object, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -340,7 +318,7 @@ struct pw_client_node_proxy_events { uint32_t offset, uint32_t size); - void (*set_activation) (void *object, + int (*set_activation) (void *object, uint32_t node_id, int signalfd, uint32_t mem_id, diff --git a/src/extensions/protocol-native.h b/src/extensions/protocol-native.h index 5f2da3aba..00756e5b5 100644 --- a/src/extensions/protocol-native.h +++ b/src/extensions/protocol-native.h @@ -51,8 +51,8 @@ struct pw_protocol_native_ext { uint32_t (*add_proxy_fd) (struct pw_proxy *proxy, int fd); int (*get_proxy_fd) (struct pw_proxy *proxy, uint32_t index); - void (*end_proxy) (struct pw_proxy *proxy, - struct spa_pod_builder *builder); + int (*end_proxy) (struct pw_proxy *proxy, + struct spa_pod_builder *builder); struct spa_pod_builder * (*begin_resource) (struct pw_resource *resource, uint8_t opcode); @@ -60,8 +60,8 @@ struct pw_protocol_native_ext { uint32_t (*add_resource_fd) (struct pw_resource *resource, int fd); int (*get_resource_fd) (struct pw_resource *resource, uint32_t index); - void (*end_resource) (struct pw_resource *resource, - struct spa_pod_builder *builder); + int (*end_resource) (struct pw_resource *resource, + struct spa_pod_builder *builder); }; diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 87781b449..aa47b914d 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -281,7 +281,7 @@ static void add_pending(GstPipeWireDeviceProvider *self, struct pending *p, p->data = data; p->seq = ++self->seq; pw_log_debug("add pending %d", p->seq); - pw_core_proxy_sync(self->core_proxy, p->seq); + pw_core_proxy_sync(self->core_proxy, 0, p->seq); } static void remove_pending(struct pending *p) @@ -293,7 +293,7 @@ static void remove_pending(struct pending *p) } } -static void +static int on_core_info (void *data, const struct pw_core_info *info) { GstPipeWireDeviceProvider *self = data; @@ -301,7 +301,7 @@ on_core_info (void *data, const struct pw_core_info *info) const gchar *value; if (info == NULL || info->props == NULL) - return; + return -EINVAL; value = spa_dict_lookup (info->props, "monitors"); if (value) { @@ -318,10 +318,11 @@ on_core_info (void *data, const struct pw_core_info *info) } g_strfreev (monitors); } + return 0; } -static void -on_core_done (void *data, uint32_t seq) +static int +on_core_done (void *data, uint32_t id, uint32_t seq) { GstPipeWireDeviceProvider *self = data; struct pending *p, *t; @@ -339,6 +340,7 @@ on_core_done (void *data, uint32_t seq) if (self->main_loop) pw_thread_loop_signal (self->main_loop, FALSE); } + return 0; } static const struct pw_core_proxy_events core_events = { @@ -371,13 +373,14 @@ on_state_changed (void *data, enum pw_remote_state old, enum pw_remote_state sta pw_thread_loop_signal (self->main_loop, FALSE); } -static void port_event_info(void *data, const struct pw_port_info *info) +static int port_event_info(void *data, const struct pw_port_info *info) { struct port_data *port_data = data; pw_log_debug("%p", port_data); + return 0; } -static void port_event_param(void *data, uint32_t id, uint32_t index, uint32_t next, +static int port_event_param(void *data, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct port_data *port_data = data; @@ -389,7 +392,7 @@ static void port_event_param(void *data, uint32_t id, uint32_t index, uint32_t n c1 = gst_caps_from_format (param); if (c1 && node_data->caps) gst_caps_append (node_data->caps, c1); - + return 0; } static const struct pw_port_proxy_events port_events = { @@ -398,11 +401,12 @@ static const struct pw_port_proxy_events port_events = { .param = port_event_param }; -static void node_event_info(void *data, const struct pw_node_info *info) +static int node_event_info(void *data, const struct pw_node_info *info) { struct node_data *node_data = data; pw_log_debug("%p", node_data); node_data->info = pw_node_info_update(node_data->info, info); + return 0; } static const struct pw_node_proxy_events node_events = { @@ -451,9 +455,9 @@ static const struct pw_proxy_events proxy_port_events = { .destroy = destroy_port_proxy, }; -static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, uint32_t permissions, - uint32_t type, uint32_t version, - const struct spa_dict *props) +static int registry_event_global(void *data, uint32_t id, uint32_t parent_id, uint32_t permissions, + uint32_t type, uint32_t version, + const struct spa_dict *props) { struct remote_data *rd = data; GstPipeWireDeviceProvider *self = rd->self; @@ -484,7 +488,7 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, u struct port_data *pd; if ((nd = find_node_data(rd, parent_id)) == NULL) - return; + return -EINVAL; port = pw_registry_proxy_bind(rd->registry, id, PW_TYPE_INTERFACE_Port, @@ -504,15 +508,16 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, u add_pending(self, &pd->pending, do_add_node, pd); } - return; + return 0; no_mem: GST_ERROR_OBJECT(self, "failed to create proxy"); - return; + return -ENOMEM; } -static void registry_event_global_remove(void *data, uint32_t id) +static int registry_event_global_remove(void *data, uint32_t id) { + return 0; } static const struct pw_registry_proxy_events registry_events = { @@ -586,7 +591,7 @@ gst_pipewire_device_provider_probe (GstDeviceProvider * provider) data->registry = pw_core_proxy_get_registry(self->core_proxy, PW_TYPE_INTERFACE_Registry, PW_VERSION_REGISTRY, 0); pw_registry_proxy_add_listener(data->registry, &data->registry_listener, ®istry_events, data); - pw_core_proxy_sync(self->core_proxy, ++self->seq); + pw_core_proxy_sync(self->core_proxy, 0, ++self->seq); for (;;) { if (pw_remote_get_state(r, NULL) <= 0) @@ -676,7 +681,7 @@ gst_pipewire_device_provider_start (GstDeviceProvider * provider) data->registry = self->registry; pw_registry_proxy_add_listener(self->registry, &data->registry_listener, ®istry_events, data); - pw_core_proxy_sync(self->core_proxy, ++self->seq); + pw_core_proxy_sync(self->core_proxy, 0, ++self->seq); for (;;) { if (self->end) diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index 5217969cc..b96d1d321 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -146,8 +146,6 @@ struct node { uint32_t n_params; struct spa_pod **params; - - uint32_t seq; }; struct impl { @@ -396,9 +394,7 @@ static int impl_node_set_param(struct spa_node *node, uint32_t id, uint32_t flag if (this->resource == NULL) return 0; - pw_client_node_resource_set_param(this->resource, this->seq, id, flags, param); - - return SPA_RESULT_RETURN_ASYNC(this->seq++); + return pw_client_node_resource_set_param(this->resource, id, flags, param); } static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size_t size) @@ -448,7 +444,6 @@ static int impl_node_set_io(struct spa_node *node, uint32_t id, void *data, size static int impl_node_send_command(struct spa_node *node, const struct spa_command *command) { struct node *this; - int res = 0; spa_return_val_if_fail(node != NULL, -EINVAL); spa_return_val_if_fail(command != NULL, -EINVAL); @@ -458,10 +453,8 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman if (this->resource == NULL) return 0; - pw_client_node_resource_command(this->resource, this->seq, command); - res = SPA_RESULT_RETURN_ASYNC(this->seq++); - - return res; + pw_log_debug("client-node %p: send command %d", node, SPA_COMMAND_TYPE(command)); + return pw_client_node_resource_command(this->resource, command); } @@ -497,6 +490,16 @@ impl_node_set_callbacks(struct spa_node *node, return 0; } +static int +impl_node_sync(struct spa_node *node, uint32_t seq) +{ + 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); +} + static void do_update_port(struct node *this, struct port *port, @@ -585,11 +588,7 @@ impl_node_add_port(struct spa_node *node, enum spa_direction direction, uint32_t spa_return_val_if_fail(CHECK_FREE_PORT(this, direction, port_id), -EINVAL); - pw_client_node_resource_add_port(this->resource, - this->seq, - direction, port_id); - - return SPA_RESULT_RETURN_ASYNC(this->seq++); + return pw_client_node_resource_add_port(this->resource, direction, port_id); } static int @@ -602,11 +601,7 @@ impl_node_remove_port(struct spa_node *node, enum spa_direction direction, uint3 spa_return_val_if_fail(CHECK_PORT(this, direction, port_id), -EINVAL); - pw_client_node_resource_remove_port(this->resource, - this->seq, - direction, port_id); - - return SPA_RESULT_RETURN_ASYNC(this->seq++); + return pw_client_node_resource_remove_port(this->resource, direction, port_id); } static int @@ -667,13 +662,14 @@ impl_node_port_set_param(struct spa_node *node, if (this->resource == NULL) return 0; - pw_client_node_resource_port_set_param(this->resource, - this->seq, + pw_log_debug("node %p: port %d.%d add param %s %d", this, + direction, port_id, + spa_debug_type_find_name(spa_type_param, id), id); + + return pw_client_node_resource_port_set_param(this->resource, direction, port_id, id, flags, param); - - return SPA_RESULT_RETURN_ASYNC(this->seq++); } static int do_port_set_io(struct impl *impl, @@ -722,15 +718,12 @@ static int do_port_set_io(struct impl *impl, update_io(this, mix->ios, id, memid); - pw_client_node_resource_port_set_io(this->resource, - this->seq, + return pw_client_node_resource_port_set_io(this->resource, direction, port_id, mix_id, id, memid, mem_offset, mem_size); - - return SPA_RESULT_RETURN_ASYNC(this->seq++); } static int @@ -855,12 +848,9 @@ do_port_use_buffers(struct impl *impl, } } - pw_client_node_resource_port_use_buffers(this->resource, - this->seq, + return pw_client_node_resource_port_use_buffers(this->resource, direction, port_id, mix_id, n_buffers, mb); - - return SPA_RESULT_RETURN_ASYNC(this->seq++); } static int @@ -946,16 +936,7 @@ static int impl_node_process(struct spa_node *node) return SPA_STATUS_OK; } -static void -client_node_done(void *data, int seq, int res) -{ - struct impl *impl = data; - struct node *this = &impl->node; - if (this->callbacks && this->callbacks->done) - this->callbacks->done(this->callbacks_data, seq, res); -} - -static void +static int client_node_update(void *data, uint32_t change_mask, uint32_t max_input_ports, @@ -988,9 +969,10 @@ client_node_update(void *data, } spa_log_debug(this->log, "node %p: got node update max_in %u, max_out %u", this, this->max_inputs, this->max_outputs); + return 0; } -static void +static int client_node_port_update(void *data, enum spa_direction direction, uint32_t port_id, @@ -1006,7 +988,7 @@ client_node_port_update(void *data, spa_log_debug(this->log, "node %p: got port update", this); if (!CHECK_PORT_ID(this, direction, port_id)) - return; + return -EINVAL; remove = (change_mask == 0); @@ -1033,25 +1015,26 @@ client_node_port_update(void *data, info && (change_mask & PW_CLIENT_NODE_PORT_UPDATE_INFO)) this->callbacks->port_info(this->callbacks_data, direction, port_id, info); } + return 0; } -static void client_node_set_active(void *data, bool active) +static int client_node_set_active(void *data, bool active) { struct impl *impl = data; - pw_node_set_active(impl->this.node, active); + return pw_node_set_active(impl->this.node, active); } -static void client_node_event(void *data, struct spa_event *event) +static int client_node_event(void *data, struct spa_event *event) { struct impl *impl = data; struct node *this = &impl->node; if (this->callbacks && this->callbacks->event) this->callbacks->event(this->callbacks_data, event); + return 0; } static struct pw_client_node_proxy_methods client_node_methods = { PW_VERSION_CLIENT_NODE_PROXY_METHODS, - .done = client_node_done, .update = client_node_update, .port_update = client_node_port_update, .set_active = client_node_set_active, @@ -1082,11 +1065,12 @@ static void node_on_data_fd_events(struct spa_source *source) static const struct spa_node impl_node = { SPA_VERSION_NODE, NULL, + .set_callbacks = impl_node_set_callbacks, + .sync = impl_node_sync, .enum_params = impl_node_enum_params, .set_param = impl_node_set_param, .set_io = impl_node_set_io, .send_command = impl_node_send_command, - .set_callbacks = impl_node_set_callbacks, .add_port = impl_node_add_port, .remove_port = impl_node_remove_port, .port_enum_params = impl_node_port_enum_params, @@ -1133,9 +1117,7 @@ node_init(struct node *this, this->data_source.mask = SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP; this->data_source.rmask = 0; - this->seq = 1; - - return SPA_RESULT_RETURN_ASYNC(this->seq++); + return 0; } static int node_clear(struct node *this) @@ -1186,6 +1168,25 @@ static void client_node_resource_destroy(void *data) pw_node_destroy(this->node); } +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; + + 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)); +} + void pw_client_node_registered(struct pw_client_node *this, uint32_t node_id) { struct impl *impl = SPA_CONTAINER_OF(this, struct impl, this); @@ -1541,6 +1542,8 @@ static const struct pw_node_events node_events = { static const struct pw_resource_events resource_events = { PW_VERSION_RESOURCE_EVENTS, .destroy = client_node_resource_destroy, + .error = client_node_resource_error, + .done = client_node_resource_done, }; static int root_impl_process(void *data, struct spa_graph_node *node) @@ -1630,6 +1633,8 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource, pw_node_add_listener(this->node, &impl->node_listener, &node_events, impl); + pw_resource_sync(this->resource, 0); + return this; error_no_node: diff --git a/src/modules/module-client-node/client-stream.c b/src/modules/module-client-node/client-stream.c index 6edc10a7b..b1a9a5d47 100644 --- a/src/modules/module-client-node/client-stream.c +++ b/src/modules/module-client-node/client-stream.c @@ -281,11 +281,10 @@ static int impl_node_send_command(struct spa_node *node, const struct spa_comman if ((res = spa_node_send_command(impl->cnode, command)) < 0) return res; } - - return 0; + return res; } -static void adapter_port_info(void *data, +static int adapter_port_info(void *data, enum spa_direction direction, uint32_t port_id, const struct spa_port_info *info) { @@ -297,6 +296,7 @@ static void adapter_port_info(void *data, this->callbacks->port_info(this->callbacks_data, direction, port_id, info); } } + return 0; } static const struct spa_node_callbacks adapter_node_callbacks = { @@ -326,6 +326,20 @@ impl_node_set_callbacks(struct spa_node *node, return 0; } +static int +impl_node_sync(struct spa_node *node, uint32_t seq) +{ + 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_sync(impl->cnode, seq); +} + static int impl_node_add_port(struct spa_node *node, enum spa_direction direction, uint32_t port_id) { @@ -816,11 +830,12 @@ static int impl_node_process(struct spa_node *node) static const struct spa_node impl_node = { SPA_VERSION_NODE, + .set_callbacks = impl_node_set_callbacks, + .sync = impl_node_sync, .enum_params = impl_node_enum_params, .set_param = impl_node_set_param, .set_io = impl_node_set_io, .send_command = impl_node_send_command, - .set_callbacks = impl_node_set_callbacks, .add_port = impl_node_add_port, .remove_port = impl_node_remove_port, .port_enum_params = impl_node_port_enum_params, @@ -1077,7 +1092,7 @@ static void client_node_async_complete(void *data, uint32_t seq, int res) 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, res); + node->callbacks->done(node->callbacks_data, seq); } static void client_node_active_changed(void *data, bool active) diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index 4a701ed91..240aac989 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -31,23 +31,7 @@ #include #include -static void -client_node_marshal_done(void *object, int seq, int res) -{ - struct pw_proxy *proxy = object; - struct spa_pod_builder *b; - - b = pw_protocol_native_begin_proxy(proxy, PW_CLIENT_NODE_PROXY_METHOD_DONE); - - spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), - SPA_POD_Int(res)); - - pw_protocol_native_end_proxy(proxy, b); -} - - -static void +static int client_node_marshal_update(void *object, uint32_t change_mask, uint32_t max_input_ports, @@ -83,10 +67,10 @@ client_node_marshal_update(void *object, } spa_pod_builder_pop(b, &f); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void +static int client_node_marshal_port_update(void *object, enum spa_direction direction, uint32_t port_id, @@ -133,10 +117,10 @@ client_node_marshal_port_update(void *object, } spa_pod_builder_pop(b, &f[0]); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void client_node_marshal_set_active(void *object, bool active) +static int client_node_marshal_set_active(void *object, bool active) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -146,10 +130,10 @@ static void client_node_marshal_set_active(void *object, bool active) spa_pod_builder_add_struct(b, SPA_POD_Bool(active)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void client_node_marshal_event_method(void *object, struct spa_event *event) +static int client_node_marshal_event_method(void *object, struct spa_event *event) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -159,7 +143,7 @@ static void client_node_marshal_event_method(void *object, struct spa_event *eve spa_pod_builder_add_struct(b, SPA_POD_Pod(event)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int client_node_demarshal_add_mem(void *object, void *data, size_t size) @@ -215,18 +199,17 @@ static int client_node_demarshal_set_param(void *object, void *data, size_t size { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t seq, id, flags; + uint32_t id, flags; const struct spa_pod *param = NULL; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), SPA_POD_Id(&id), SPA_POD_Int(&flags), SPA_POD_PodObject(¶m)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, 0, seq, id, flags, param); + pw_proxy_notify(proxy, struct pw_client_node_proxy_events, set_param, 0, id, flags, param); return 0; } @@ -250,15 +233,13 @@ static int client_node_demarshal_command(void *object, void *data, size_t size) struct pw_proxy *proxy = object; struct spa_pod_parser prs; const struct spa_command *command; - uint32_t seq; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), SPA_POD_PodObject(&command)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, command, 0, seq, command); + pw_proxy_notify(proxy, struct pw_client_node_proxy_events, command, 0, command); return 0; } @@ -266,16 +247,15 @@ static int client_node_demarshal_add_port(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - int32_t seq, direction, port_id; + int32_t direction, port_id; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), SPA_POD_Int(&direction), SPA_POD_Int(&port_id)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_port, 0, seq, direction, port_id); + pw_proxy_notify(proxy, struct pw_client_node_proxy_events, add_port, 0, direction, port_id); return 0; } @@ -283,16 +263,15 @@ static int client_node_demarshal_remove_port(void *object, void *data, size_t si { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - int32_t seq, direction, port_id; + int32_t direction, port_id; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), SPA_POD_Int(&direction), SPA_POD_Int(&port_id)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, remove_port, 0, seq, direction, port_id); + pw_proxy_notify(proxy, struct pw_client_node_proxy_events, remove_port, 0, direction, port_id); return 0; } @@ -300,12 +279,11 @@ static int client_node_demarshal_port_set_param(void *object, void *data, size_t { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t seq, direction, port_id, id, flags; + uint32_t direction, port_id, id, flags; const struct spa_pod *param = NULL; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), SPA_POD_Int(&direction), SPA_POD_Int(&port_id), SPA_POD_Id(&id), @@ -314,7 +292,7 @@ static int client_node_demarshal_port_set_param(void *object, void *data, size_t return -EINVAL; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_set_param, 0, - seq, direction, port_id, id, flags, param); + direction, port_id, id, flags, param); return 0; } @@ -323,14 +301,13 @@ static int client_node_demarshal_port_use_buffers(void *object, void *data, size struct pw_proxy *proxy = object; struct spa_pod_parser prs; struct spa_pod_frame f; - uint32_t seq, direction, port_id, mix_id, n_buffers, data_id; + uint32_t direction, port_id, mix_id, n_buffers, data_id; struct pw_client_node_buffer *buffers; uint32_t i, j; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_push_struct(&prs, &f) < 0 || spa_pod_parser_get(&prs, - SPA_POD_Int(&seq), SPA_POD_Int(&direction), SPA_POD_Int(&port_id), SPA_POD_Int(&mix_id), @@ -376,7 +353,7 @@ static int client_node_demarshal_port_use_buffers(void *object, void *data, size d->data = SPA_UINT32_TO_PTR(data_id); } } - pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_use_buffers, 0, seq, + pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_use_buffers, 0, direction, port_id, mix_id, @@ -388,11 +365,10 @@ static int client_node_demarshal_port_set_io(void *object, void *data, size_t si { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t seq, direction, port_id, mix_id, id, memid, off, sz; + uint32_t direction, port_id, mix_id, id, memid, off, sz; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), SPA_POD_Int(&direction), SPA_POD_Int(&port_id), SPA_POD_Int(&mix_id), @@ -403,7 +379,6 @@ static int client_node_demarshal_port_set_io(void *object, void *data, size_t si return -EINVAL; pw_proxy_notify(proxy, struct pw_client_node_proxy_events, port_set_io, 0, - seq, direction, port_id, mix_id, id, memid, off, sz); @@ -457,7 +432,7 @@ static int client_node_demarshal_set_io(void *object, void *data, size_t size) return 0; } -static void +static int client_node_marshal_add_mem(void *object, uint32_t mem_id, uint32_t type, @@ -474,10 +449,10 @@ client_node_marshal_add_mem(void *object, SPA_POD_Int(pw_protocol_native_add_resource_fd(resource, memfd)), SPA_POD_Int(flags)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd) +static int client_node_marshal_transport(void *object, uint32_t node_id, int readfd, int writefd) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -489,11 +464,11 @@ static void client_node_marshal_transport(void *object, uint32_t node_id, int re SPA_POD_Int(pw_protocol_native_add_resource_fd(resource, readfd)), SPA_POD_Int(pw_protocol_native_add_resource_fd(resource, writefd))); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void -client_node_marshal_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags, +static int +client_node_marshal_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -502,15 +477,14 @@ client_node_marshal_set_param(void *object, uint32_t seq, uint32_t id, uint32_t b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_SET_PARAM); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), SPA_POD_Id(id), SPA_POD_Int(flags), SPA_POD_Pod(param)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void client_node_marshal_event_event(void *object, const struct spa_event *event) +static int client_node_marshal_event_event(void *object, const struct spa_event *event) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -520,11 +494,11 @@ static void client_node_marshal_event_event(void *object, const struct spa_event spa_pod_builder_add_struct(b, SPA_POD_Pod(event)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void -client_node_marshal_command(void *object, uint32_t seq, const struct spa_command *command) +static int +client_node_marshal_command(void *object, const struct spa_command *command) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -532,15 +506,14 @@ client_node_marshal_command(void *object, uint32_t seq, const struct spa_command b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_COMMAND); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), SPA_POD_Pod(command)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_add_port(void *object, - uint32_t seq, enum spa_direction direction, uint32_t port_id) + enum spa_direction direction, uint32_t port_id) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -548,16 +521,15 @@ client_node_marshal_add_port(void *object, b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_ADD_PORT); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), SPA_POD_Int(direction), SPA_POD_Int(port_id)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_remove_port(void *object, - uint32_t seq, enum spa_direction direction, uint32_t port_id) + enum spa_direction direction, uint32_t port_id) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -565,16 +537,14 @@ client_node_marshal_remove_port(void *object, b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_REMOVE_PORT); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), SPA_POD_Int(direction), SPA_POD_Int(port_id)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_port_set_param(void *object, - uint32_t seq, enum spa_direction direction, uint32_t port_id, uint32_t id, @@ -587,19 +557,17 @@ client_node_marshal_port_set_param(void *object, b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_PARAM); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), SPA_POD_Int(direction), SPA_POD_Int(port_id), SPA_POD_Id(id), SPA_POD_Int(flags), SPA_POD_Pod(param)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_port_use_buffers(void *object, - uint32_t seq, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, @@ -614,7 +582,6 @@ client_node_marshal_port_use_buffers(void *object, spa_pod_builder_push_struct(b, &f); spa_pod_builder_add(b, - SPA_POD_Int(seq), SPA_POD_Int(direction), SPA_POD_Int(port_id), SPA_POD_Int(mix_id), @@ -649,12 +616,11 @@ client_node_marshal_port_use_buffers(void *object, } spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_port_set_io(void *object, - uint32_t seq, uint32_t direction, uint32_t port_id, uint32_t mix_id, @@ -669,7 +635,6 @@ client_node_marshal_port_set_io(void *object, b = pw_protocol_native_begin_resource(resource, PW_CLIENT_NODE_PROXY_EVENT_PORT_SET_IO); spa_pod_builder_add_struct(b, - SPA_POD_Int(seq), SPA_POD_Int(direction), SPA_POD_Int(port_id), SPA_POD_Int(mix_id), @@ -678,10 +643,10 @@ client_node_marshal_port_set_io(void *object, SPA_POD_Int(offset), SPA_POD_Int(size)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_set_activation(void *object, uint32_t node_id, int signalfd, @@ -701,10 +666,10 @@ client_node_marshal_set_activation(void *object, SPA_POD_Int(offset), SPA_POD_Int(size)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void +static int client_node_marshal_set_io(void *object, uint32_t id, uint32_t memid, @@ -720,23 +685,7 @@ client_node_marshal_set_io(void *object, SPA_POD_Int(memid), SPA_POD_Int(offset), SPA_POD_Int(size)); - pw_protocol_native_end_resource(resource, b); -} - -static int client_node_demarshal_done(void *object, void *data, size_t size) -{ - struct pw_resource *resource = object; - struct spa_pod_parser prs; - uint32_t seq, res; - - spa_pod_parser_init(&prs, data, size); - if (spa_pod_parser_get_struct(&prs, - SPA_POD_Int(&seq), - SPA_POD_Int(&res)) < 0) - return -EINVAL; - - pw_resource_do(resource, struct pw_client_node_proxy_methods, done, 0, seq, res); - return 0; + return pw_protocol_native_end_resource(resource, b); } static int client_node_demarshal_update(void *object, void *data, size_t size) @@ -882,7 +831,6 @@ static int client_node_demarshal_event_method(void *object, void *data, size_t s static const struct pw_client_node_proxy_methods pw_protocol_native_client_node_method_marshal = { PW_VERSION_CLIENT_NODE_PROXY_METHODS, - &client_node_marshal_done, &client_node_marshal_update, &client_node_marshal_port_update, &client_node_marshal_set_active, @@ -890,7 +838,6 @@ static const struct pw_client_node_proxy_methods pw_protocol_native_client_node_ }; static const struct pw_protocol_native_demarshal pw_protocol_native_client_node_method_demarshal[] = { - { &client_node_demarshal_done, 0 }, { &client_node_demarshal_update, 0 }, { &client_node_demarshal_port_update, 0 }, { &client_node_demarshal_set_active, 0 }, diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index 1fd94dcce..50ad44093 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -343,9 +343,9 @@ static struct mix *ensure_mix(struct node_data *data, return mix; } -static void client_node_add_mem(void *object, - uint32_t mem_id, - uint32_t type, int memfd, uint32_t flags) +static int client_node_add_mem(void *object, + uint32_t mem_id, + uint32_t type, int memfd, uint32_t flags) { struct pw_proxy *proxy = object; struct node_data *data = proxy->user_data; @@ -355,7 +355,7 @@ static void client_node_add_mem(void *object, if (m) { pw_log_warn("duplicate mem %u, fd %d, flags %d", mem_id, memfd, flags); - return; + return -EINVAL; } m = pw_array_add(&data->mems, sizeof(struct mem)); @@ -367,10 +367,11 @@ static void client_node_add_mem(void *object, m->ref = 0; m->map.map = PW_MAP_RANGE_INIT; m->map.ptr = NULL; + return 0; } -static void client_node_transport(void *object, uint32_t node_id, - int readfd, int writefd) +static int client_node_transport(void *object, uint32_t node_id, + int readfd, int writefd) { struct pw_proxy *proxy = object; struct node_data *data = proxy->user_data; @@ -392,14 +393,16 @@ static void client_node_transport(void *object, uint32_t node_id, pw_client_node_proxy_set_active(data->node_proxy, true); pw_remote_events_exported(remote, proxy->id, node_id); + return 0; } -static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_t change_mask) +static int add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32_t change_mask) { struct node_data *data = proxy->user_data; struct spa_port_info pi = SPA_PORT_INFO_INIT(); uint32_t n_params = 0; struct spa_pod **params = NULL; + int res; if (change_mask & PW_CLIENT_NODE_PORT_UPDATE_PARAMS) { uint32_t idx1, idx2, id; @@ -446,7 +449,7 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32 pi.flags &= ~SPA_PORT_FLAG_CAN_ALLOC_BUFFERS; } - pw_client_node_proxy_port_update(data->node_proxy, + res = pw_client_node_proxy_port_update(data->node_proxy, port->direction, port->port_id, change_mask, @@ -458,17 +461,19 @@ static void add_port_update(struct pw_proxy *proxy, struct pw_port *port, uint32 free(params[--n_params]); free(params); } + return res; } -static void -client_node_set_param(void *object, uint32_t seq, uint32_t id, uint32_t flags, +static int +client_node_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { pw_log_warn("set param not implemented"); + return -ENOTSUP; } -static void +static int client_node_set_io(void *object, uint32_t id, uint32_t memid, @@ -488,12 +493,12 @@ client_node_set_io(void *object, m = find_mem(data, memid); if (m == NULL) { pw_log_warn("unknown memory id %u", memid); - return; + return -EINVAL; } ptr = mem_map(data, &m->map, m->fd, PROT_READ|PROT_WRITE, offset, size); if (ptr == NULL) - return; + return -errno; m->ref++; } @@ -508,12 +513,13 @@ client_node_set_io(void *object, } data->position = ptr; } - spa_node_set_io(data->node->node, id, ptr, size); + return spa_node_set_io(data->node->node, id, ptr, size); } -static void client_node_event(void *object, const struct spa_event *event) +static int client_node_event(void *object, const struct spa_event *event) { pw_log_warn("unhandled node event %d", SPA_EVENT_TYPE(event)); + return -ENOTSUP; } static int @@ -527,7 +533,7 @@ do_pause_source(struct spa_loop *loop, return 0; } -static void client_node_command(void *object, uint32_t seq, const struct spa_command *command) +static int client_node_command(void *object, const struct spa_command *command) { struct pw_proxy *proxy = object; struct node_data *data = proxy->user_data; @@ -536,50 +542,58 @@ static void client_node_command(void *object, uint32_t seq, const struct spa_com switch (SPA_NODE_COMMAND_ID(command)) { case SPA_NODE_COMMAND_Pause: - pw_log_debug("node %p: pause %d", proxy, seq); + pw_log_debug("node %p: pause", proxy); if (data->rtsocket_source) { pw_loop_invoke(data->core->data_loop, do_pause_source, 1, NULL, 0, true, data); } - if ((res = pw_node_set_state(data->node, PW_NODE_STATE_IDLE)) < 0) + if ((res = pw_node_set_state(data->node, PW_NODE_STATE_IDLE)) < 0) { pw_log_warn("node %p: pause failed", proxy); + pw_proxy_error(proxy, res, "pause failed"); + } - pw_client_node_proxy_done(data->node_proxy, seq, res); break; case SPA_NODE_COMMAND_Start: - pw_log_debug("node %p: start %d", proxy, seq); + pw_log_debug("node %p: start", proxy); if ((res = pw_node_set_state(data->node, PW_NODE_STATE_RUNNING)) < 0) { pw_log_warn("node %p: start failed", proxy); + pw_proxy_error(proxy, res, "start failed"); } else if (data->rtsocket_source) { pw_loop_update_io(remote->core->data_loop, data->rtsocket_source, SPA_IO_IN | SPA_IO_ERR | SPA_IO_HUP); } - - pw_client_node_proxy_done(data->node_proxy, seq, res); break; default: pw_log_warn("unhandled node command %d", SPA_NODE_COMMAND_ID(command)); - pw_client_node_proxy_done(data->node_proxy, seq, -ENOTSUP); + res = -ENOTSUP; + pw_proxy_error(proxy, res, "command %d not supported", SPA_NODE_COMMAND_ID(command)); } + return res; } -static void -client_node_add_port(void *object, uint32_t seq, enum spa_direction direction, uint32_t port_id) +static int +client_node_add_port(void *object, enum spa_direction direction, uint32_t port_id) { + struct pw_proxy *proxy = object; pw_log_warn("add port not supported"); + pw_proxy_error(proxy, -ENOTSUP, "add port not supported"); + return -ENOTSUP; } -static void -client_node_remove_port(void *object, uint32_t seq, enum spa_direction direction, uint32_t port_id) +static int +client_node_remove_port(void *object, enum spa_direction direction, uint32_t port_id) { + struct pw_proxy *proxy = object; pw_log_warn("remove port not supported"); + pw_proxy_error(proxy, -ENOTSUP, "remove port not supported"); + return -ENOTSUP; } -static void clear_buffers(struct node_data *data, struct mix *mix) +static int clear_buffers(struct node_data *data, struct mix *mix) { struct pw_port *port = mix->port; struct buffer *b; @@ -589,7 +603,7 @@ static void clear_buffers(struct node_data *data, struct mix *mix) pw_log_debug("port %p: clear buffers %d", port, mix->mix_id); if ((res = pw_port_use_buffers(port, mix->mix_id, NULL, 0)) < 0) { pw_log_error("port %p: error clear buffers %s", port, spa_strerror(res)); - return; + return res; } pw_array_for_each(b, &mix->buffers) { @@ -608,11 +622,11 @@ static void clear_buffers(struct node_data *data, struct mix *mix) free(b->buf); } mix->buffers.size = 0; + return 0; } -static void +static int client_node_port_set_param(void *object, - uint32_t seq, enum spa_direction direction, uint32_t port_id, uint32_t id, uint32_t flags, const struct spa_pod *param) @@ -625,6 +639,7 @@ client_node_port_set_param(void *object, port = pw_node_find_port(data->node, direction, port_id); if (port == NULL) { res = -EINVAL; + pw_proxy_error(proxy, res, "unknown port"); goto done; } @@ -639,20 +654,22 @@ client_node_port_set_param(void *object, } res = pw_port_set_param(port, SPA_ID_INVALID, id, flags, param); - if (res < 0) + if (res < 0) { + pw_proxy_error(proxy, res, "can't set port param: %s", spa_strerror(res)); goto done; + } - add_port_update(proxy, port, + if ((res = add_port_update(proxy, port, PW_CLIENT_NODE_PORT_UPDATE_PARAMS | - PW_CLIENT_NODE_PORT_UPDATE_INFO); + PW_CLIENT_NODE_PORT_UPDATE_INFO)) < 0) + pw_proxy_error(proxy, res, "can't add port update"); done: - pw_client_node_proxy_done(data->node_proxy, seq, res); + return res; } -static void +static int client_node_port_use_buffers(void *object, - uint32_t seq, enum spa_direction direction, uint32_t port_id, uint32_t mix_id, uint32_t n_buffers, struct pw_client_node_buffer *buffers) { @@ -667,6 +684,7 @@ client_node_port_use_buffers(void *object, mix = ensure_mix(data, direction, port_id, mix_id); if (mix == NULL) { res = -EINVAL; + pw_proxy_error(proxy, res, "can add mix"); goto done; } @@ -687,6 +705,7 @@ client_node_port_use_buffers(void *object, if (m == NULL) { pw_log_error("unknown memory id %u", buffers[i].mem_id); res = -EINVAL; + pw_proxy_error(proxy, res, "unknown memory %u", buffers[i].mem_id); goto cleanup; } @@ -698,6 +717,7 @@ client_node_port_use_buffers(void *object, buffers[i].offset, buffers[i].size); if (bmem.map.ptr == NULL) { res = -errno; + pw_proxy_error(proxy, res, "can't mmap memory: %s", spa_strerror(res)); goto cleanup; } if (mlock(bmem.map.ptr, bmem.map.map.size) < 0) @@ -716,6 +736,7 @@ client_node_port_use_buffers(void *object, b = bid->buf = malloc(size); if (b == NULL) { res = -ENOMEM; + pw_proxy_error(proxy, res, "can't alloc memory: %s", spa_strerror(res)); goto cleanup; } memcpy(b, buffers[i].buffer, sizeof(struct spa_buffer)); @@ -757,6 +778,7 @@ client_node_port_use_buffers(void *object, if (bm == NULL) { pw_log_error("unknown buffer mem %u", mem_id); res = -EINVAL; + pw_proxy_error(proxy, res, "unknown buffer mem %u", mem_id); goto cleanup; } @@ -783,11 +805,11 @@ client_node_port_use_buffers(void *object, bufs[i] = b; } - res = pw_port_use_buffers(mix->port, mix->mix_id, bufs, n_buffers); + if ((res = pw_port_use_buffers(mix->port, mix->mix_id, bufs, n_buffers)) < 0) + pw_proxy_error(proxy, res, "can't use buffers: %s", spa_strerror(res)); done: - pw_client_node_proxy_done(data->node_proxy, seq, res); - return; + return res; cleanup: clear_buffers(data, mix); @@ -795,9 +817,8 @@ client_node_port_use_buffers(void *object, } -static void +static int client_node_port_set_io(void *object, - uint32_t seq, uint32_t direction, uint32_t port_id, uint32_t mix_id, @@ -811,10 +832,14 @@ client_node_port_set_io(void *object, struct mix *mix; struct mem *m; void *ptr; + int res = 0; mix = ensure_mix(data, direction, port_id, mix_id); - if (mix == NULL) - return; + if (mix == NULL) { + res = -EINVAL; + pw_proxy_error(proxy, res, "can't get mixer: %s", spa_strerror(res)); + return res; + } if (memid == SPA_ID_INVALID) { ptr = NULL; @@ -824,12 +849,17 @@ client_node_port_set_io(void *object, m = find_mem(data, memid); if (m == NULL) { pw_log_warn("unknown memory id %u", memid); - return; + res = -EINVAL; + pw_proxy_error(proxy, res, "unknown memory id %u", memid); + return res; } ptr = mem_map(data, &m->map, m->fd, PROT_READ|PROT_WRITE, offset, size); - if (ptr == NULL) - return; + if (ptr == NULL) { + res = -errno; + pw_proxy_error(proxy, res, "mmap failed: %s", spa_strerror(res)); + return res; + } m->ref++; } @@ -848,12 +878,14 @@ client_node_port_set_io(void *object, if (ptr) activate_mix(data, mix); } else { - spa_node_port_set_io(mix->port->node->node, + if ((res = spa_node_port_set_io(mix->port->node->node, direction, port_id, id, ptr, - size); + size)) < 0) + pw_proxy_error(proxy, res, "set_io failed: %s", spa_strerror(res)); } + return res; } #if 0 @@ -868,7 +900,7 @@ static int link_signal_func(void *user_data) } #endif -static void +static int client_node_set_activation(void *object, uint32_t node_id, int signalfd, @@ -881,6 +913,7 @@ client_node_set_activation(void *object, struct pw_node *node = data->node; struct mem *m; struct pw_node_activation *ptr; + int res = 0; if (memid == SPA_ID_INVALID) { ptr = NULL; @@ -890,12 +923,17 @@ client_node_set_activation(void *object, m = find_mem(data, memid); if (m == NULL) { pw_log_warn("unknown memory id %u", memid); - return; + res = -EINVAL; + pw_proxy_error(proxy, res, "unknown memory id %u", memid); + return res; } ptr = mem_map(data, &m->map, m->fd, PROT_READ|PROT_WRITE, offset, size); - if (ptr == NULL) - return; + if (ptr == NULL) { + res = -errno; + pw_proxy_error(proxy, res, "mmap failed: %s", spa_strerror(res)); + return res; + } m->ref++; } pw_log_debug("node %p: set activation %d", node, node_id); @@ -914,6 +952,7 @@ client_node_set_activation(void *object, link->link.state->pending); } #endif + return res; } static const struct pw_client_node_proxy_events client_node_events = { @@ -956,7 +995,6 @@ static void do_node_init(struct pw_proxy *proxy) PW_CLIENT_NODE_PORT_UPDATE_PARAMS | PW_CLIENT_NODE_PORT_UPDATE_INFO); } - pw_client_node_proxy_done(data->node_proxy, 0, 0); } static void clear_mix(struct node_data *data, struct mix *mix) diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index cf27e57b4..6c3e0e0c7 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -476,8 +476,7 @@ on_remote_data(void *data, int fd, enum spa_io mask) if (mask & SPA_IO_IN) { uint8_t opcode; - uint32_t id; - uint32_t size; + uint32_t id, size; void *message; while (!impl->disconnecting @@ -773,11 +772,11 @@ static int impl_ext_get_proxy_fd(struct pw_proxy *proxy, uint32_t index) return pw_protocol_native_connection_get_fd(impl->connection, index); } -static void impl_ext_end_proxy(struct pw_proxy *proxy, +static int impl_ext_end_proxy(struct pw_proxy *proxy, struct spa_pod_builder *builder) { struct client *impl = SPA_CONTAINER_OF(proxy->remote->conn, struct client, this); - pw_protocol_native_connection_end(impl->connection, builder); + return pw_protocol_native_connection_end(impl->connection, builder); } static struct spa_pod_builder * @@ -798,11 +797,11 @@ static int impl_ext_get_resource_fd(struct pw_resource *resource, uint32_t index return pw_protocol_native_connection_get_fd(data->connection, index); } -static void impl_ext_end_resource(struct pw_resource *resource, +static int impl_ext_end_resource(struct pw_resource *resource, struct spa_pod_builder *builder) { struct client_data *data = resource->client->user_data; - pw_protocol_native_connection_end(data->connection, builder); + return pw_protocol_native_connection_end(data->connection, builder); } const static struct pw_protocol_native_ext protocol_ext_impl = { diff --git a/src/modules/module-protocol-native/connection.c b/src/modules/module-protocol-native/connection.c index c4225eacf..17af01cfe 100644 --- a/src/modules/module-protocol-native/connection.c +++ b/src/modules/module-protocol-native/connection.c @@ -65,8 +65,8 @@ struct impl { uint32_t dest_id; uint8_t opcode; struct spa_pod_builder builder; - struct pw_core *core; + uint32_t seq; }; /** \endcond */ @@ -398,16 +398,20 @@ pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection * return &impl->builder; } -void +int pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn, struct spa_pod_builder *builder) { struct impl *impl = SPA_CONTAINER_OF(conn, struct impl, this); uint32_t *p, size = builder->state.offset; struct buffer *buf = &impl->out; + uint32_t seq; if ((p = connection_ensure_size(conn, buf, 8 + size)) == NULL) - return; + return -ENOMEM; + + seq = impl->seq; + impl->seq = (impl->seq + 1) & SPA_ASYNC_SEQ_MASK; *p++ = impl->dest_id; *p++ = (impl->opcode << 24) | (size & 0xffffff); @@ -418,8 +422,11 @@ pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn, fprintf(stderr, ">>>>>>>>> out: %d %d %d\n", impl->dest_id, impl->opcode, size); spa_debug_pod(0, NULL, (struct spa_pod *)p); } + spa_hook_list_call(&conn->listener_list, struct pw_protocol_native_connection_events, need_flush, 0); + + return SPA_RESULT_RETURN_ASYNC(seq); } /** Flush the connection object diff --git a/src/modules/module-protocol-native/connection.h b/src/modules/module-protocol-native/connection.h index ec064384e..3f4a3bdb7 100644 --- a/src/modules/module-protocol-native/connection.h +++ b/src/modules/module-protocol-native/connection.h @@ -90,7 +90,7 @@ struct spa_pod_builder * pw_protocol_native_connection_begin_proxy(struct pw_protocol_native_connection *conn, struct pw_proxy *proxy, uint8_t opcode); -void +int pw_protocol_native_connection_end(struct pw_protocol_native_connection *conn, struct spa_pod_builder *builder); diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 3fddc41b1..26aed5bb0 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -32,7 +32,7 @@ #include "connection.h" -static void core_marshal_hello(void *object, uint32_t version) +static int core_method_marshal_hello(void *object, uint32_t version) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -42,10 +42,10 @@ static void core_marshal_hello(void *object, uint32_t version) spa_pod_builder_add_struct(b, SPA_POD_Int(version)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void core_marshal_sync(void *object, uint32_t seq) +static int core_method_marshal_sync(void *object, uint32_t id, uint32_t seq) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -53,12 +53,42 @@ static void core_marshal_sync(void *object, uint32_t seq) b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_SYNC); spa_pod_builder_add_struct(b, + SPA_POD_Int(id), SPA_POD_Int(seq)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void core_marshal_get_registry(void *object, uint32_t version, uint32_t new_id) +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); + + spa_pod_builder_add_struct(b, + SPA_POD_Int(id), + SPA_POD_Int(seq)); + + return pw_protocol_native_end_proxy(proxy, b); +} + +static int core_method_marshal_error(void *object, uint32_t id, int res, const char *error) +{ + struct pw_proxy *proxy = object; + struct spa_pod_builder *b; + + b = pw_protocol_native_begin_proxy(proxy, PW_CORE_PROXY_METHOD_ERROR); + + spa_pod_builder_add_struct(b, + SPA_POD_Int(id), + SPA_POD_Int(res), + SPA_POD_String(error)); + + return pw_protocol_native_end_proxy(proxy, b); +} + +static int core_method_marshal_get_registry(void *object, uint32_t version, uint32_t new_id) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -69,7 +99,7 @@ static void core_marshal_get_registry(void *object, uint32_t version, uint32_t n SPA_POD_Int(version), SPA_POD_Int(new_id)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static void push_dict(struct spa_pod_builder *b, const struct spa_dict *dict) @@ -88,8 +118,8 @@ static void push_dict(struct spa_pod_builder *b, const struct spa_dict *dict) spa_pod_builder_pop(b, &f); } -static void -core_marshal_create_object(void *object, +static int +core_method_marshal_create_object(void *object, const char *factory_name, uint32_t type, uint32_t version, const struct spa_dict *props, uint32_t new_id) @@ -110,11 +140,11 @@ core_marshal_create_object(void *object, spa_pod_builder_int(b, new_id); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void -core_marshal_destroy(void *object, uint32_t id) +static int +core_method_marshal_destroy(void *object, uint32_t id) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -124,10 +154,10 @@ core_marshal_destroy(void *object, uint32_t id) spa_pod_builder_add_struct(b, SPA_POD_Int(id)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static int core_demarshal_info(void *object, void *data, size_t size) +static int core_event_demarshal_info(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_dict props; @@ -164,26 +194,40 @@ static int core_demarshal_info(void *object, void *data, size_t size) NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_core_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_core_proxy_events, info, 0, &info); } -static int core_demarshal_done(void *object, void *data, size_t size) +static int core_event_demarshal_done(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; - uint32_t seq; + uint32_t id, seq; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&id), SPA_POD_Int(&seq)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_core_proxy_events, done, 0, seq); - return 0; + return pw_proxy_notify(proxy, struct pw_core_proxy_events, done, 0, id, seq); } -static int core_demarshal_error(void *object, void *data, size_t size) +static int core_event_demarshal_sync(void *object, void *data, size_t size) +{ + struct pw_proxy *proxy = object; + struct spa_pod_parser prs; + uint32_t id, seq; + + spa_pod_parser_init(&prs, data, size); + if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&id), + SPA_POD_Int(&seq)) < 0) + return -EINVAL; + + return pw_proxy_notify(proxy, struct pw_core_proxy_events, sync, 0, id, seq); +} + +static int core_event_demarshal_error(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -197,11 +241,10 @@ static int core_demarshal_error(void *object, void *data, size_t size) SPA_POD_String(&error)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_core_proxy_events, error, 0, id, res, error); - return 0; + return pw_proxy_notify(proxy, struct pw_core_proxy_events, error, 0, id, res, error); } -static int core_demarshal_remove_id(void *object, void *data, size_t size) +static int core_event_demarshal_remove_id(void *object, void *data, size_t size) { struct pw_proxy *proxy = object; struct spa_pod_parser prs; @@ -211,11 +254,10 @@ static int core_demarshal_remove_id(void *object, void *data, size_t size) if (spa_pod_parser_get_struct(&prs, SPA_POD_Int(&id)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_core_proxy_events, remove_id, 0, id); - return 0; + return pw_proxy_notify(proxy, struct pw_core_proxy_events, remove_id, 0, id); } -static void core_marshal_info(void *object, const struct pw_core_info *info) +static int core_event_marshal_info(void *object, const struct pw_core_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -236,10 +278,10 @@ static void core_marshal_info(void *object, const struct pw_core_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void core_marshal_done(void *object, uint32_t seq) +static int core_event_marshal_done(void *object, uint32_t id, uint32_t seq) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -247,12 +289,27 @@ static void core_marshal_done(void *object, uint32_t seq) b = pw_protocol_native_begin_resource(resource, PW_CORE_PROXY_EVENT_DONE); spa_pod_builder_add_struct(b, + SPA_POD_Int(id), SPA_POD_Int(seq)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void core_marshal_error(void *object, uint32_t id, int res, const char *error) +static int core_event_marshal_sync(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_SYNC); + + spa_pod_builder_add_struct(b, + SPA_POD_Int(id), + SPA_POD_Int(seq)); + + return pw_protocol_native_end_resource(resource, b); +} + +static int core_event_marshal_error(void *object, uint32_t id, int res, const char *error) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -264,10 +321,10 @@ static void core_marshal_error(void *object, uint32_t id, int res, const char *e SPA_POD_Int(res), SPA_POD_String(error)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void core_marshal_remove_id(void *object, uint32_t id) +static int core_event_marshal_remove_id(void *object, uint32_t id) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -277,10 +334,10 @@ static void core_marshal_remove_id(void *object, uint32_t id) spa_pod_builder_add_struct(b, SPA_POD_Int(id)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static int core_demarshal_hello(void *object, void *data, size_t size) +static int core_method_demarshal_hello(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -291,26 +348,57 @@ static int core_demarshal_hello(void *object, void *data, size_t size) SPA_POD_Int(&version)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_core_proxy_methods, hello, 0, version); - return 0; + return pw_resource_do(resource, struct pw_core_proxy_methods, hello, 0, version); } -static int core_demarshal_sync(void *object, void *data, size_t size) +static int core_method_demarshal_sync(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; - uint32_t seq; + uint32_t id, seq; spa_pod_parser_init(&prs, data, size); if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&id), SPA_POD_Int(&seq)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_core_proxy_methods, sync, 0, seq); - return 0; + return pw_resource_do(resource, struct pw_core_proxy_methods, sync, 0, id, seq); } -static int core_demarshal_get_registry(void *object, void *data, size_t size) +static int core_method_demarshal_done(void *object, void *data, size_t size) +{ + struct pw_resource *resource = object; + struct spa_pod_parser prs; + uint32_t id, seq; + + spa_pod_parser_init(&prs, data, size); + if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&id), + SPA_POD_Int(&seq)) < 0) + return -EINVAL; + + return pw_resource_do(resource, struct pw_core_proxy_methods, done, 0, id, seq); +} + +static int core_method_demarshal_error(void *object, void *data, size_t size) +{ + struct pw_resource *resource = object; + struct spa_pod_parser prs; + uint32_t id, res; + const char *error; + + spa_pod_parser_init(&prs, data, size); + if (spa_pod_parser_get_struct(&prs, + SPA_POD_Int(&id), + SPA_POD_Int(&res), + SPA_POD_String(&error)) < 0) + return -EINVAL; + + return pw_resource_do(resource, struct pw_core_proxy_methods, error, 0, id, res, error); +} + +static int core_method_demarshal_get_registry(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -322,11 +410,10 @@ static int core_demarshal_get_registry(void *object, void *data, size_t size) SPA_POD_Int(&new_id)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_core_proxy_methods, get_registry, 0, version, new_id); - return 0; + return pw_resource_do(resource, struct pw_core_proxy_methods, get_registry, 0, version, new_id); } -static int core_demarshal_create_object(void *object, void *data, size_t size) +static int core_method_demarshal_create_object(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -362,13 +449,12 @@ static int core_demarshal_create_object(void *object, void *data, size_t size) SPA_POD_Int(&new_id), NULL) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_core_proxy_methods, create_object, 0, factory_name, + return pw_resource_do(resource, struct pw_core_proxy_methods, create_object, 0, factory_name, type, version, &props, new_id); - return 0; } -static int core_demarshal_destroy(void *object, void *data, size_t size) +static int core_method_demarshal_destroy(void *object, void *data, size_t size) { struct pw_resource *resource = object; struct spa_pod_parser prs; @@ -379,11 +465,10 @@ static int core_demarshal_destroy(void *object, void *data, size_t size) SPA_POD_Int(&id)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_core_proxy_methods, destroy, 0, id); - return 0; + return pw_resource_do(resource, struct pw_core_proxy_methods, destroy, 0, id); } -static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_id, uint32_t permissions, +static int registry_marshal_global(void *object, uint32_t id, uint32_t parent_id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props) { struct pw_resource *resource = object; @@ -403,10 +488,10 @@ static void registry_marshal_global(void *object, uint32_t id, uint32_t parent_i push_dict(b, props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } -static void registry_marshal_global_remove(void *object, uint32_t id) +static int registry_marshal_global_remove(void *object, uint32_t id) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -415,7 +500,7 @@ static void registry_marshal_global_remove(void *object, uint32_t id) spa_pod_builder_add_struct(b, SPA_POD_Int(id)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int registry_demarshal_bind(void *object, void *data, size_t size) @@ -432,8 +517,7 @@ static int registry_demarshal_bind(void *object, void *data, size_t size) SPA_POD_Int(&new_id)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_registry_proxy_methods, bind, 0, id, type, version, new_id); - return 0; + return pw_resource_do(resource, struct pw_registry_proxy_methods, bind, 0, id, type, version, new_id); } static int registry_demarshal_destroy(void *object, void *data, size_t size) @@ -447,11 +531,10 @@ static int registry_demarshal_destroy(void *object, void *data, size_t size) SPA_POD_Int(&id)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_registry_proxy_methods, destroy, 0, id); - return 0; + return pw_resource_do(resource, struct pw_registry_proxy_methods, destroy, 0, id); } -static void module_marshal_info(void *object, const struct pw_module_info *info) +static int module_marshal_info(void *object, const struct pw_module_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -470,7 +553,7 @@ static void module_marshal_info(void *object, const struct pw_module_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int module_demarshal_info(void *object, void *data, size_t size) @@ -505,11 +588,10 @@ static int module_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_module_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_module_proxy_events, info, 0, &info); } -static void device_marshal_info(void *object, const struct pw_device_info *info) +static int device_marshal_info(void *object, const struct pw_device_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -526,7 +608,7 @@ static void device_marshal_info(void *object, const struct pw_device_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int device_demarshal_info(void *object, void *data, size_t size) @@ -559,11 +641,10 @@ static int device_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_device_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_device_proxy_events, info, 0, &info); } -static void device_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int device_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -577,7 +658,7 @@ static void device_marshal_param(void *object, uint32_t id, uint32_t index, uint SPA_POD_Int(next), SPA_POD_Pod(param)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int device_demarshal_param(void *object, void *data, size_t size) @@ -595,11 +676,10 @@ static int device_demarshal_param(void *object, void *data, size_t size) SPA_POD_Pod(¶m)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_device_proxy_events, param, 0, id, index, next, param); - return 0; + return pw_proxy_notify(proxy, struct pw_device_proxy_events, param, 0, id, index, next, param); } -static void device_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, +static int device_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_proxy *proxy = object; @@ -613,7 +693,7 @@ static void device_marshal_enum_params(void *object, uint32_t id, uint32_t index SPA_POD_Int(num), SPA_POD_Pod(filter)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int device_demarshal_enum_params(void *object, void *data, size_t size) @@ -631,11 +711,10 @@ static int device_demarshal_enum_params(void *object, void *data, size_t size) SPA_POD_Pod(&filter)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_device_proxy_methods, enum_params, 0, id, index, num, filter); - return 0; + return pw_resource_do(resource, struct pw_device_proxy_methods, enum_params, 0, id, index, num, filter); } -static void device_marshal_set_param(void *object, uint32_t id, uint32_t flags, +static int device_marshal_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { struct pw_proxy *proxy = object; @@ -647,7 +726,7 @@ static void device_marshal_set_param(void *object, uint32_t id, uint32_t flags, SPA_POD_Id(id), SPA_POD_Int(flags), SPA_POD_Pod(param)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int device_demarshal_set_param(void *object, void *data, size_t size) @@ -664,11 +743,10 @@ static int device_demarshal_set_param(void *object, void *data, size_t size) SPA_POD_Pod(¶m)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_device_proxy_methods, set_param, 0, id, flags, param); - return 0; + return pw_resource_do(resource, struct pw_device_proxy_methods, set_param, 0, id, flags, param); } -static void factory_marshal_info(void *object, const struct pw_factory_info *info) +static int factory_marshal_info(void *object, const struct pw_factory_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -687,7 +765,7 @@ static void factory_marshal_info(void *object, const struct pw_factory_info *inf push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int factory_demarshal_info(void *object, void *data, size_t size) @@ -722,11 +800,10 @@ static int factory_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_factory_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_factory_proxy_events, info, 0, &info); } -static void node_marshal_info(void *object, const struct pw_node_info *info) +static int node_marshal_info(void *object, const struct pw_node_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -749,7 +826,7 @@ static void node_marshal_info(void *object, const struct pw_node_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int node_demarshal_info(void *object, void *data, size_t size) @@ -788,11 +865,10 @@ static int node_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_node_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_node_proxy_events, info, 0, &info); } -static void node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int node_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -806,7 +882,7 @@ static void node_marshal_param(void *object, uint32_t id, uint32_t index, uint32 SPA_POD_Int(next), SPA_POD_Pod(param)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int node_demarshal_param(void *object, void *data, size_t size) @@ -824,11 +900,10 @@ static int node_demarshal_param(void *object, void *data, size_t size) SPA_POD_Pod(¶m)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_node_proxy_events, param, 0, id, index, next, param); - return 0; + return pw_proxy_notify(proxy, struct pw_node_proxy_events, param, 0, id, index, next, param); } -static void node_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, +static int node_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_proxy *proxy = object; @@ -842,7 +917,7 @@ static void node_marshal_enum_params(void *object, uint32_t id, uint32_t index, SPA_POD_Int(num), SPA_POD_Pod(filter)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int node_demarshal_enum_params(void *object, void *data, size_t size) @@ -860,11 +935,10 @@ static int node_demarshal_enum_params(void *object, void *data, size_t size) SPA_POD_Pod(&filter)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_node_proxy_methods, enum_params, 0, id, index, num, filter); - return 0; + return pw_resource_do(resource, struct pw_node_proxy_methods, enum_params, 0, id, index, num, filter); } -static void node_marshal_set_param(void *object, uint32_t id, uint32_t flags, +static int node_marshal_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { struct pw_proxy *proxy = object; @@ -876,7 +950,7 @@ static void node_marshal_set_param(void *object, uint32_t id, uint32_t flags, SPA_POD_Id(id), SPA_POD_Int(flags), SPA_POD_Pod(param)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int node_demarshal_set_param(void *object, void *data, size_t size) @@ -893,11 +967,10 @@ static int node_demarshal_set_param(void *object, void *data, size_t size) SPA_POD_Pod(¶m)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_node_proxy_methods, set_param, 0, id, flags, param); - return 0; + return pw_resource_do(resource, struct pw_node_proxy_methods, set_param, 0, id, flags, param); } -static void node_marshal_send_command(void *object, const struct spa_command *command) +static int node_marshal_send_command(void *object, const struct spa_command *command) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -905,7 +978,7 @@ static void node_marshal_send_command(void *object, const struct spa_command *co b = pw_protocol_native_begin_proxy(proxy, PW_NODE_PROXY_METHOD_SEND_COMMAND); spa_pod_builder_add_struct(b, SPA_POD_Pod(command)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int node_demarshal_send_command(void *object, void *data, size_t size) @@ -919,11 +992,10 @@ static int node_demarshal_send_command(void *object, void *data, size_t size) SPA_POD_Pod(&command)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_node_proxy_methods, send_command, 0, command); - return 0; + return pw_resource_do(resource, struct pw_node_proxy_methods, send_command, 0, command); } -static void port_marshal_info(void *object, const struct pw_port_info *info) +static int port_marshal_info(void *object, const struct pw_port_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -940,7 +1012,7 @@ static void port_marshal_info(void *object, const struct pw_port_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int port_demarshal_info(void *object, void *data, size_t size) @@ -973,11 +1045,10 @@ static int port_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_port_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_port_proxy_events, info, 0, &info); } -static void port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int port_marshal_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -991,7 +1062,7 @@ static void port_marshal_param(void *object, uint32_t id, uint32_t index, uint32 SPA_POD_Int(next), SPA_POD_Pod(param)); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int port_demarshal_param(void *object, void *data, size_t size) @@ -1009,11 +1080,10 @@ static int port_demarshal_param(void *object, void *data, size_t size) SPA_POD_Pod(¶m)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_port_proxy_events, param, 0, id, index, next, param); - return 0; + return pw_proxy_notify(proxy, struct pw_port_proxy_events, param, 0, id, index, next, param); } -static void port_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, +static int port_marshal_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_proxy *proxy = object; @@ -1027,7 +1097,7 @@ static void port_marshal_enum_params(void *object, uint32_t id, uint32_t index, SPA_POD_Int(num), SPA_POD_Pod(filter)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int port_demarshal_enum_params(void *object, void *data, size_t size) @@ -1045,11 +1115,10 @@ static int port_demarshal_enum_params(void *object, void *data, size_t size) SPA_POD_Pod(&filter)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_port_proxy_methods, enum_params, 0, id, index, num, filter); - return 0; + return pw_resource_do(resource, struct pw_port_proxy_methods, enum_params, 0, id, index, num, filter); } -static void client_marshal_info(void *object, const struct pw_client_info *info) +static int client_marshal_info(void *object, const struct pw_client_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -1065,7 +1134,7 @@ static void client_marshal_info(void *object, const struct pw_client_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int client_demarshal_info(void *object, void *data, size_t size) @@ -1097,11 +1166,10 @@ static int client_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_client_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_client_proxy_events, info, 0, &info); } -static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_permissions, +static int client_marshal_permissions(void *object, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions) { struct pw_resource *resource = object; @@ -1130,7 +1198,7 @@ static void client_marshal_permissions(void *object, uint32_t index, uint32_t n_ spa_pod_builder_pop(b, &f[1]); spa_pod_builder_pop(b, &f[0]); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int client_demarshal_permissions(void *object, void *data, size_t size) @@ -1159,11 +1227,10 @@ static int client_demarshal_permissions(void *object, void *data, size_t size) SPA_POD_Int(&permissions[i].permissions), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_client_proxy_events, permissions, 0, index, n_permissions, permissions); - return 0; + return pw_proxy_notify(proxy, struct pw_client_proxy_events, permissions, 0, index, n_permissions, permissions); } -static void client_marshal_error(void *object, uint32_t id, int res, const char *error) +static int client_marshal_error(void *object, uint32_t id, int res, const char *error) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -1173,7 +1240,7 @@ static void client_marshal_error(void *object, uint32_t id, int res, const char SPA_POD_Int(id), SPA_POD_Int(res), SPA_POD_String(error)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int client_demarshal_error(void *object, void *data, size_t size) @@ -1190,11 +1257,10 @@ static int client_demarshal_error(void *object, void *data, size_t size) SPA_POD_String(&error)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_client_proxy_methods, error, 0, id, res, error); - return 0; + return pw_resource_do(resource, struct pw_client_proxy_methods, error, 0, id, res, error); } -static void client_marshal_get_permissions(void *object, uint32_t index, uint32_t num) +static int client_marshal_get_permissions(void *object, uint32_t index, uint32_t num) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -1205,10 +1271,10 @@ static void client_marshal_get_permissions(void *object, uint32_t index, uint32_ SPA_POD_Int(index), SPA_POD_Int(num)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void client_marshal_update_properties(void *object, const struct spa_dict *props) +static int client_marshal_update_properties(void *object, const struct spa_dict *props) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -1220,7 +1286,7 @@ static void client_marshal_update_properties(void *object, const struct spa_dict push_dict(b, props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int client_demarshal_update_properties(void *object, void *data, size_t size) @@ -1245,9 +1311,8 @@ static int client_demarshal_update_properties(void *object, void *data, size_t s SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_resource_do(resource, struct pw_client_proxy_methods, update_properties, 0, + return pw_resource_do(resource, struct pw_client_proxy_methods, update_properties, 0, &props); - return 0; } static int client_demarshal_get_permissions(void *object, void *data, size_t size) @@ -1262,11 +1327,10 @@ static int client_demarshal_get_permissions(void *object, void *data, size_t siz SPA_POD_Int(&num)) < 0) return -EINVAL; - pw_resource_do(resource, struct pw_client_proxy_methods, get_permissions, 0, index, num); - return 0; + return pw_resource_do(resource, struct pw_client_proxy_methods, get_permissions, 0, index, num); } -static void client_marshal_update_permissions(void *object, uint32_t n_permissions, +static int client_marshal_update_permissions(void *object, uint32_t n_permissions, const struct pw_permission *permissions) { struct pw_proxy *proxy = object; @@ -1284,7 +1348,7 @@ static void client_marshal_update_permissions(void *object, uint32_t n_permissio } spa_pod_builder_pop(b, &f); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static int client_demarshal_update_permissions(void *object, void *data, size_t size) @@ -1308,12 +1372,11 @@ static int client_demarshal_update_permissions(void *object, void *data, size_t SPA_POD_Int(&permissions[i].permissions), NULL) < 0) return -EINVAL; } - pw_resource_do(resource, struct pw_client_proxy_methods, update_permissions, 0, + return pw_resource_do(resource, struct pw_client_proxy_methods, update_permissions, 0, n_permissions, permissions); - return 0; } -static void link_marshal_info(void *object, const struct pw_link_info *info) +static int link_marshal_info(void *object, const struct pw_link_info *info) { struct pw_resource *resource = object; struct spa_pod_builder *b; @@ -1336,7 +1399,7 @@ static void link_marshal_info(void *object, const struct pw_link_info *info) push_dict(b, info->props); spa_pod_builder_pop(b, &f); - pw_protocol_native_end_resource(resource, b); + return pw_protocol_native_end_resource(resource, b); } static int link_demarshal_info(void *object, void *data, size_t size) @@ -1375,8 +1438,7 @@ static int link_demarshal_info(void *object, void *data, size_t size) SPA_POD_String(&props.items[i].value), NULL) < 0) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_link_proxy_events, info, 0, &info); - return 0; + return pw_proxy_notify(proxy, struct pw_link_proxy_events, info, 0, &info); } static int registry_demarshal_global(void *object, void *data, size_t size) @@ -1410,10 +1472,9 @@ static int registry_demarshal_global(void *object, void *data, size_t size) return -EINVAL; } - pw_proxy_notify(proxy, struct pw_registry_proxy_events, + return pw_proxy_notify(proxy, struct pw_registry_proxy_events, global, 0, id, parent_id, permissions, type, version, props.n_items > 0 ? &props : NULL); - return 0; } static int registry_demarshal_global_remove(void *object, void *data, size_t size) @@ -1427,11 +1488,10 @@ static int registry_demarshal_global_remove(void *object, void *data, size_t siz SPA_POD_Int(&id)) < 0) return -EINVAL; - pw_proxy_notify(proxy, struct pw_registry_proxy_events, global_remove, 0, id); - return 0; + return pw_proxy_notify(proxy, struct pw_registry_proxy_events, global_remove, 0, id); } -static void registry_marshal_bind(void *object, uint32_t id, +static int registry_marshal_bind(void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id) { struct pw_proxy *proxy = object; @@ -1445,10 +1505,10 @@ static void registry_marshal_bind(void *object, uint32_t id, SPA_POD_Int(version), SPA_POD_Int(new_id)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } -static void registry_marshal_destroy(void *object, uint32_t id) +static int registry_marshal_destroy(void *object, uint32_t id) { struct pw_proxy *proxy = object; struct spa_pod_builder *b; @@ -1456,39 +1516,45 @@ static void registry_marshal_destroy(void *object, uint32_t id) b = pw_protocol_native_begin_proxy(proxy, PW_REGISTRY_PROXY_METHOD_DESTROY); spa_pod_builder_add_struct(b, SPA_POD_Int(id)); - pw_protocol_native_end_proxy(proxy, b); + return pw_protocol_native_end_proxy(proxy, b); } static const struct pw_core_proxy_methods pw_protocol_native_core_method_marshal = { PW_VERSION_CORE_PROXY_METHODS, - &core_marshal_hello, - &core_marshal_sync, - &core_marshal_get_registry, - &core_marshal_create_object, - &core_marshal_destroy, + &core_method_marshal_hello, + &core_method_marshal_sync, + &core_method_marshal_done, + &core_method_marshal_error, + &core_method_marshal_get_registry, + &core_method_marshal_create_object, + &core_method_marshal_destroy, }; static const struct pw_protocol_native_demarshal pw_protocol_native_core_method_demarshal[PW_CORE_PROXY_METHOD_NUM] = { - { &core_demarshal_hello, 0, }, - { &core_demarshal_sync, 0, }, - { &core_demarshal_get_registry, 0, }, - { &core_demarshal_create_object, 0, }, - { &core_demarshal_destroy, 0, } + { &core_method_demarshal_hello, 0, }, + { &core_method_demarshal_sync, 0, }, + { &core_method_demarshal_done, 0, }, + { &core_method_demarshal_error, 0, }, + { &core_method_demarshal_get_registry, 0, }, + { &core_method_demarshal_create_object, 0, }, + { &core_method_demarshal_destroy, 0, } }; static const struct pw_core_proxy_events pw_protocol_native_core_event_marshal = { PW_VERSION_CORE_PROXY_EVENTS, - &core_marshal_done, - &core_marshal_error, - &core_marshal_remove_id, - &core_marshal_info + &core_event_marshal_info, + &core_event_marshal_done, + &core_event_marshal_sync, + &core_event_marshal_error, + &core_event_marshal_remove_id, }; static const struct pw_protocol_native_demarshal pw_protocol_native_core_event_demarshal[PW_CORE_PROXY_EVENT_NUM] = { - { &core_demarshal_done, 0, }, - { &core_demarshal_error, 0, }, - { &core_demarshal_remove_id, 0, }, - { &core_demarshal_info, 0, }, + { &core_event_demarshal_info, 0, }, + { &core_event_demarshal_done, 0, }, + { &core_event_demarshal_sync, 0, }, + { &core_event_demarshal_error, 0, }, + { &core_event_demarshal_remove_id, 0, }, }; static const struct pw_protocol_marshal pw_protocol_native_core_marshal = { diff --git a/src/modules/spa/spa-monitor.c b/src/modules/spa/spa-monitor.c index ac7591af4..d14059f88 100644 --- a/src/modules/spa/spa-monitor.c +++ b/src/modules/spa/spa-monitor.c @@ -242,7 +242,7 @@ static void change_item(struct pw_spa_monitor *this, struct spa_pod *item, uint6 } } -static void on_monitor_event(void *data, struct spa_event *event) +static int on_monitor_event(void *data, struct spa_event *event) { struct impl *impl = data; struct pw_spa_monitor *this = &impl->this; @@ -265,6 +265,7 @@ static void on_monitor_event(void *data, struct spa_event *event) change_item(this, item, now_nsec); break; } + return 0; } static void update_monitor(struct pw_core *core, const char *name) diff --git a/src/pipewire/client.c b/src/pipewire/client.c index 5c2bda26a..9d22d3deb 100644 --- a/src/pipewire/client.c +++ b/src/pipewire/client.c @@ -102,7 +102,7 @@ client_permission_func(struct pw_global *global, return p->permissions; } -static void client_error(void *object, uint32_t id, int res, const char *error) +static int client_error(void *object, uint32_t id, int res, const char *error) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); @@ -112,24 +112,25 @@ static void client_error(void *object, uint32_t id, int res, const char *error) global = pw_core_find_global(client->core, id); if (global == NULL) - return; + return -ENOENT; spa_list_for_each_safe(r, t, &global->resource_list, link) { if (t->client != client) continue; pw_resource_error(r, res, error); } + return 0; } -static void client_update_properties(void *object, const struct spa_dict *props) +static int client_update_properties(void *object, const struct spa_dict *props) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); struct pw_client *client = data->client; - pw_client_update_properties(client, props); + return pw_client_update_properties(client, props); } -static void client_get_permissions(void *object, uint32_t index, uint32_t num) +static int client_get_permissions(void *object, uint32_t index, uint32_t num) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); @@ -143,17 +144,17 @@ static void client_get_permissions(void *object, uint32_t index, uint32_t num) else if ((size_t)index + (size_t)num >= len) num = len - index; - pw_client_resource_permissions(resource, index, + return pw_client_resource_permissions(resource, index, num, pw_array_get_unchecked(&impl->permissions, index, struct pw_permission)); } -static void client_update_permissions(void *object, +static int client_update_permissions(void *object, uint32_t n_permissions, const struct pw_permission *permissions) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); struct pw_client *client = data->client; - pw_client_update_permissions(client, n_permissions, permissions); + return pw_client_update_permissions(client, n_permissions, permissions); } static const struct pw_client_proxy_methods client_methods = { diff --git a/src/pipewire/core.c b/src/pipewire/core.c index e4c74458b..ec713c061 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -57,8 +57,8 @@ struct resource_data { /** \endcond */ -static void registry_bind(void *object, uint32_t id, - uint32_t type, uint32_t version, uint32_t new_id) +static int registry_bind(void *object, uint32_t id, + uint32_t type, uint32_t version, uint32_t new_id) { struct pw_resource *resource = object; struct pw_client *client = resource->client; @@ -83,7 +83,7 @@ static void registry_bind(void *object, uint32_t id, if (pw_global_bind(global, client, permissions, version, new_id) < 0) goto exit; - return; + return 0; no_id: pw_log_debug("registry %p: no global with id %u to bind to %u", resource, id, new_id); @@ -99,9 +99,10 @@ static void registry_bind(void *object, uint32_t id, * new_id as 'used and freed' */ pw_map_insert_at(&client->objects, new_id, NULL); pw_core_resource_remove_id(client->core_resource, new_id); + return -EFAULT; } -static void registry_destroy(void *object, uint32_t id) +static int registry_destroy(void *object, uint32_t id) { struct pw_resource *resource = object; struct pw_client *client = resource->client; @@ -120,13 +121,13 @@ static void registry_destroy(void *object, uint32_t id) pw_log_debug("global %p: destroy global id %d", global, id); pw_global_destroy(global); - return; + return 0; no_id: pw_log_debug("registry %p: no global with id %u to destroy", resource, id); goto exit; exit: - return; + return -EFAULT; } static const struct pw_registry_proxy_methods registry_methods = { @@ -146,26 +147,56 @@ static const struct pw_resource_events resource_events = { .destroy = destroy_registry_resource }; -static void core_hello(void *object, uint32_t version) +static int core_hello(void *object, uint32_t version) { struct pw_resource *resource = object; struct pw_core *this = resource->core; - pw_log_debug("core %p: hello %d from source %p", this, version, resource); - + pw_log_debug("core %p: hello %d from resource %p", this, version, resource); this->info.change_mask = PW_CORE_CHANGE_MASK_ALL; pw_core_resource_info(resource, &this->info); + return 0; } -static void core_sync(void *object, uint32_t seq) +static int core_sync(void *object, uint32_t id, uint32_t seq) { struct pw_resource *resource = object; - - pw_log_debug("core %p: sync %d from resource %p", resource->core, seq, resource); - pw_core_resource_done(resource, seq); + pw_log_debug("core %p: sync %d for resource %d", resource->core, seq, id); + pw_core_resource_done(resource, id, seq); + return 0; } -static void core_get_registry(void *object, uint32_t version, uint32_t new_id) +static int core_done(void *object, uint32_t id, uint32_t seq) +{ + struct pw_resource *resource = object; + struct pw_client *client = resource->client; + struct pw_resource *r; + + pw_log_debug("core %p: done %d for resource %d", resource->core, seq, id); + + if ((r = pw_client_find_resource(client, id)) == NULL) + return -EINVAL; + + pw_resource_events_done(r, seq); + return 0; +} + +static int core_error(void *object, uint32_t id, int res, const char *message) +{ + struct pw_resource *resource = object; + struct pw_client *client = resource->client; + struct pw_resource *r; + + pw_log_debug("core %p: error %d for resource %d: %s", resource->core, res, id, message); + + if ((r = pw_client_find_resource(client, id)) == NULL) + return -EINVAL; + + pw_resource_events_error(r, res, message); + return 0; +} + +static int core_get_registry(void *object, uint32_t version, uint32_t new_id) { struct pw_resource *resource = object; struct pw_client *client = resource->client; @@ -209,16 +240,17 @@ static void core_get_registry(void *object, uint32_t version, uint32_t new_id) } } - return; + return 0; no_mem: pw_log_error("can't create registry resource"); pw_core_resource_error(client->core_resource, new_id, -ENOMEM, "no memory"); pw_map_insert_at(&client->objects, new_id, NULL); pw_core_resource_remove_id(client->core_resource, new_id); + return -ENOMEM; } -static void +static int core_create_object(void *object, const char *factory_name, uint32_t type, @@ -231,6 +263,7 @@ core_create_object(void *object, struct pw_factory *factory; void *obj; struct pw_properties *properties; + int res; factory = pw_core_find_factory(client->core, factory_name); if (factory == NULL || factory->global == NULL) @@ -255,32 +288,34 @@ core_create_object(void *object, /* error will be posted */ obj = pw_factory_create_object(factory, resource, type, version, properties, new_id); if (obj == NULL) - goto error; + goto create_failed; - return; + return 0; no_factory: + res = -EINVAL; pw_log_error("can't find node factory %s", factory_name); - pw_resource_error(resource, -EINVAL, "unknown factory name %s", factory_name); + pw_resource_error(resource, res, "unknown factory name %s", factory_name); goto error; wrong_version: wrong_type: + res = -EPROTO; pw_log_error("invalid resource type/version"); - pw_resource_error(resource, -EINVAL, "wrong resource type/version"); + pw_resource_error(resource, res, "wrong resource type/version"); goto error; no_properties: + res = -errno; pw_log_error("can't create properties"); - goto no_mem; - no_mem: - pw_resource_error(resource, -ENOMEM, "no memory"); - goto error; + pw_resource_error(resource, res, "no memory"); + create_failed: + res = -errno; error: pw_map_insert_at(&client->objects, new_id, NULL); pw_core_resource_remove_id(client->core_resource, new_id); - return; + return res; } -static void core_destroy(void *object, uint32_t id) +static int core_destroy(void *object, uint32_t id) { struct pw_resource *resource = object; struct pw_client *client = resource->client; @@ -292,20 +327,20 @@ static void core_destroy(void *object, uint32_t id) goto no_resource; pw_resource_destroy(r); - - done: - return; + return 0; no_resource: pw_log_error("can't find resouce %d", id); pw_resource_error(resource, -EINVAL, "unknown resource %d", id); - goto done; + return -EINVAL; } static const struct pw_core_proxy_methods core_methods = { PW_VERSION_CORE_PROXY_METHODS, .hello = core_hello, .sync = core_sync, + .done = core_done, + .error = core_error, .get_registry = core_get_registry, .create_object = core_create_object, .destroy = core_destroy, diff --git a/src/pipewire/device.c b/src/pipewire/device.c index 17e56916b..48b83965c 100644 --- a/src/pipewire/device.c +++ b/src/pipewire/device.c @@ -158,7 +158,7 @@ static int reply_param(void *data, uint32_t id, uint32_t index, uint32_t next, s return 0; } -static void device_enum_params(void *object, uint32_t id, uint32_t start, uint32_t num, +static int device_enum_params(void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter) { struct pw_resource *resource = object; @@ -170,9 +170,10 @@ static void device_enum_params(void *object, uint32_t id, uint32_t start, uint32 filter, reply_param, resource)) < 0) pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); + return res; } -static void device_set_param(void *object, uint32_t id, uint32_t flags, +static int device_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -183,6 +184,7 @@ static void device_set_param(void *object, uint32_t id, uint32_t flags, if ((res = spa_device_set_param(device->implementation, id, flags, param)) < 0) pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); + return res; } static const struct pw_device_proxy_methods device_methods = { @@ -288,11 +290,12 @@ static const struct pw_node_events node_events = { }; -static void device_info(void *data, const struct spa_device_info *info) +static int device_info(void *data, const struct spa_device_info *info) { struct pw_device *device = data; if (info->change_mask & SPA_DEVICE_CHANGE_MASK_INFO) pw_device_update_properties(device, info->info); + return 0; } static void device_add(struct pw_device *device, uint32_t id, @@ -366,7 +369,7 @@ static struct node_data *find_node(struct pw_device *device, uint32_t id) return NULL; } -static void device_object_info(void *data, uint32_t id, +static int device_object_info(void *data, uint32_t id, const struct spa_device_object_info *info) { struct pw_device *device = data; @@ -390,6 +393,7 @@ static void device_object_info(void *data, uint32_t id, else { device_add(device, id, info); } + return 0; } diff --git a/src/pipewire/interfaces.h b/src/pipewire/interfaces.h index 587f51d70..694190456 100644 --- a/src/pipewire/interfaces.h +++ b/src/pipewire/interfaces.h @@ -71,10 +71,12 @@ struct pw_link_proxy; #define PW_CORE_PROXY_METHOD_HELLO 0 #define PW_CORE_PROXY_METHOD_SYNC 1 -#define PW_CORE_PROXY_METHOD_GET_REGISTRY 2 -#define PW_CORE_PROXY_METHOD_CREATE_OBJECT 3 -#define PW_CORE_PROXY_METHOD_DESTROY 4 -#define PW_CORE_PROXY_METHOD_NUM 5 +#define PW_CORE_PROXY_METHOD_DONE 2 +#define PW_CORE_PROXY_METHOD_ERROR 3 +#define PW_CORE_PROXY_METHOD_GET_REGISTRY 4 +#define PW_CORE_PROXY_METHOD_CREATE_OBJECT 5 +#define PW_CORE_PROXY_METHOD_DESTROY 6 +#define PW_CORE_PROXY_METHOD_NUM 7 #define PW_LINK_OUTPUT_NODE_ID "link.output_node.id" #define PW_LINK_OUTPUT_PORT_ID "link.output_port.id" @@ -96,17 +98,44 @@ struct pw_core_proxy_methods { * Start a conversation with the server. This will send * the core info.. */ - void (*hello) (void *object, uint32_t version); + int (*hello) (void *object, uint32_t version); /** * Do server roundtrip * - * Ask the server to emit the 'done' event with \a id. + * Ask the server to emit the 'done' event with \a seq. + * * Since methods are handled in-order and events are delivered * in-order, this can be used as a barrier to ensure all previous * methods and the resulting events have been handled. - * \param seq the sequence number passed to the done event + * + * \param seq the seq number passed to the done event */ - void (*sync) (void *object, uint32_t seq); + int (*sync) (void *object, uint32_t id, uint32_t seq); + /** + * Reply to a server sync event. + * + * Reply to the server sync event with the same seq. + * + * \param seq the seq number received in the sync event + */ + int (*done) (void *object, uint32_t id, uint32_t seq); + /** + * Fatal error event + * + * The error method is sent out when a fatal (non-recoverable) + * error has occurred. The id argument is the proxy object where + * the error occurred, most often in response to an event on that + * object. The message is a brief description of the error, + * for (debugging) convenience. + * + * This method is usually also emited on the resource object with + * \a id. + * + * \param id object where the error occurred + * \param res error code + * \param message error description + */ + int (*error) (void *object, uint32_t id, int res, const char *message); /** * Get the registry object * @@ -115,7 +144,7 @@ struct pw_core_proxy_methods { * \param version the client proxy id * \param id the client proxy id */ - void (*get_registry) (void *object, uint32_t version, uint32_t new_id); + int (*get_registry) (void *object, uint32_t version, uint32_t new_id); /** * Create a new object on the PipeWire server from a factory. * @@ -125,7 +154,7 @@ struct pw_core_proxy_methods { * \param props extra properties * \param new_id the client proxy id */ - void (*create_object) (void *object, + int (*create_object) (void *object, const char *factory_name, uint32_t type, uint32_t version, @@ -138,19 +167,51 @@ struct pw_core_proxy_methods { * * \param id the client proxy id to destroy */ - void (*destroy) (void *object, uint32_t id); + int (*destroy) (void *object, uint32_t id); }; -static inline void +static inline int pw_core_proxy_hello(struct pw_core_proxy *core, uint32_t version) { - pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, hello, version); + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, hello, version); } -static inline void -pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t seq) +static inline int +pw_core_proxy_sync(struct pw_core_proxy *core, uint32_t id, uint32_t seq) { - pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, sync, seq); + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, sync, id, seq); +} + +static inline int +pw_core_proxy_done(struct pw_core_proxy *core, uint32_t id, uint32_t seq) +{ + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, done, id, seq); +} + +static inline int +pw_core_proxy_error(struct pw_core_proxy *core, uint32_t id, int res, const char *message) +{ + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, error, id, res, message); +} + +static inline int +pw_core_proxy_errorv(struct pw_core_proxy *core, uint32_t id, int res, const char *message, va_list args) +{ + char buffer[1024]; + vsnprintf(buffer, sizeof(buffer), message, args); + buffer[1023] = '\0'; + return pw_core_proxy_error(core, id, res, buffer); +} + +static inline int +pw_core_proxy_errorf(struct pw_core_proxy *core, uint32_t id, int res, const char *message, ...) +{ + va_list args; + int r; + va_start(args, message); + r = pw_core_proxy_errorv(core, id, res, message, args); + va_end(args); + return r; } static inline struct pw_registry_proxy * @@ -175,17 +236,18 @@ pw_core_proxy_create_object(struct pw_core_proxy *core, return p; } -static inline void +static inline int pw_core_proxy_destroy(struct pw_core_proxy *core, struct pw_proxy *proxy) { - pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, destroy, pw_proxy_get_id(proxy)); + return pw_proxy_do((struct pw_proxy*)core, struct pw_core_proxy_methods, destroy, pw_proxy_get_id(proxy)); } -#define PW_CORE_PROXY_EVENT_DONE 0 -#define PW_CORE_PROXY_EVENT_ERROR 1 -#define PW_CORE_PROXY_EVENT_REMOVE_ID 2 -#define PW_CORE_PROXY_EVENT_INFO 3 -#define PW_CORE_PROXY_EVENT_NUM 4 +#define PW_CORE_PROXY_EVENT_INFO 0 +#define PW_CORE_PROXY_EVENT_DONE 1 +#define PW_CORE_PROXY_EVENT_SYNC 2 +#define PW_CORE_PROXY_EVENT_ERROR 3 +#define PW_CORE_PROXY_EVENT_REMOVE_ID 4 +#define PW_CORE_PROXY_EVENT_NUM 5 /** \struct pw_core_proxy_events * \brief Core events @@ -194,14 +256,33 @@ pw_core_proxy_destroy(struct pw_core_proxy *core, struct pw_proxy *proxy) struct pw_core_proxy_events { #define PW_VERSION_CORE_PROXY_EVENTS 0 uint32_t version; + + /** + * Notify new core info + * + * This event is emited when first bound to the core or when the + * hello method is called. + * + * \param info new core info + */ + int (*info) (void *object, const struct pw_core_info *info); /** * Emit a done event * * The done event is emited as a result of a sync method with the - * same sequence number. - * \param seq the sequence number passed to the sync method call + * same seq number. + * + * \param seq the seq number passed to the sync method call */ - void (*done) (void *object, uint32_t seq); + int (*done) (void *object, uint32_t id, uint32_t seq); + + /** Emit a sync event + * + * The client should reply with a done reply with the same seq + * number. + */ + int (*sync) (void *object, uint32_t id, uint32_t seq); + /** * Fatal error event * @@ -218,7 +299,7 @@ struct pw_core_proxy_events { * \param res error code * \param message error description */ - void (*error) (void *object, uint32_t id, int res, const char *message); + int (*error) (void *object, uint32_t id, int res, const char *message); /** * Remove an object ID * @@ -230,13 +311,7 @@ struct pw_core_proxy_events { * * \param id deleted object ID */ - void (*remove_id) (void *object, uint32_t id); - /** - * Notify new core info - * - * \param info new core info - */ - void (*info) (void *object, const struct pw_core_info *info); + int (*remove_id) (void *object, uint32_t id); }; static inline void @@ -249,27 +324,29 @@ pw_core_proxy_add_listener(struct pw_core_proxy *core, } +#define pw_core_resource_info(r,...) pw_resource_notify(r,struct pw_core_proxy_events,info,__VA_ARGS__) #define pw_core_resource_done(r,...) pw_resource_notify(r,struct pw_core_proxy_events,done,__VA_ARGS__) +#define pw_core_resource_sync(r,...) pw_resource_notify(r,struct pw_core_proxy_events,sync,__VA_ARGS__) #define pw_core_resource_error(r,...) pw_resource_notify(r,struct pw_core_proxy_events,error,__VA_ARGS__) #define pw_core_resource_remove_id(r,...) pw_resource_notify(r,struct pw_core_proxy_events,remove_id,__VA_ARGS__) -#define pw_core_resource_info(r,...) pw_resource_notify(r,struct pw_core_proxy_events,info,__VA_ARGS__) -static inline void +static inline int pw_core_resource_errorv(struct pw_resource *resource, uint32_t id, int res, const char *message, va_list args) { char buffer[1024]; vsnprintf(buffer, sizeof(buffer), message, args); buffer[1023] = '\0'; - pw_core_resource_error(resource, id, res, buffer); + return pw_core_resource_error(resource, id, res, buffer); } -static inline void +static inline int pw_core_resource_errorf(struct pw_resource *resource, uint32_t id, int res, const char *message, ...) { va_list args; va_start(args, message); - pw_core_resource_errorv(resource, id, res, message, args); + res = pw_core_resource_errorv(resource, id, res, message, args); va_end(args); + return res; } #define PW_VERSION_REGISTRY 0 @@ -325,7 +402,7 @@ struct pw_registry_proxy_methods { * \param version the interface version to use * \param new_id the client proxy to use */ - void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id); + int (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id); /** * Attempt to destroy a global object @@ -334,7 +411,7 @@ struct pw_registry_proxy_methods { * * \param id the global id to destroy */ - void (*destroy) (void *object, uint32_t id); + int (*destroy) (void *object, uint32_t id); }; /** Registry */ @@ -349,11 +426,11 @@ pw_registry_proxy_bind(struct pw_registry_proxy *registry, return p; } -static inline void +static inline int pw_registry_proxy_destroy(struct pw_registry_proxy *registry, uint32_t id) { struct pw_proxy *reg = (struct pw_proxy*)registry; - pw_proxy_do(reg, struct pw_registry_proxy_methods, destroy, id); + return pw_proxy_do(reg, struct pw_registry_proxy_methods, destroy, id); } #define PW_REGISTRY_PROXY_EVENT_GLOBAL 0 @@ -377,9 +454,9 @@ struct pw_registry_proxy_events { * \param version the version of the interface * \param props extra properties of the global */ - void (*global) (void *object, uint32_t id, uint32_t parent_id, - uint32_t permissions, uint32_t type, uint32_t version, - const struct spa_dict *props); + int (*global) (void *object, uint32_t id, uint32_t parent_id, + uint32_t permissions, uint32_t type, uint32_t version, + const struct spa_dict *props); /** * Notify of a global object removal * @@ -389,7 +466,7 @@ struct pw_registry_proxy_events { * * \param id the id of the global that was removed */ - void (*global_remove) (void *object, uint32_t id); + int (*global_remove) (void *object, uint32_t id); }; static inline void @@ -427,7 +504,7 @@ struct pw_module_proxy_events { * * \param info info about the module */ - void (*info) (void *object, const struct pw_module_info *info); + int (*info) (void *object, const struct pw_module_info *info); }; static inline void @@ -463,8 +540,8 @@ struct pw_device_proxy_methods { * \param num the maximum number of params to retrieve * \param filter a param filter or NULL */ - void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, - const struct spa_pod *filter); + int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + const struct spa_pod *filter); /** * Set a parameter on the device * @@ -472,23 +549,23 @@ struct pw_device_proxy_methods { * \param flags extra parameter flags * \param param the parameter to set */ - void (*set_param) (void *object, uint32_t id, uint32_t flags, - const struct spa_pod *param); + int (*set_param) (void *object, uint32_t id, uint32_t flags, + const struct spa_pod *param); }; -static inline void +static inline int pw_device_proxy_enum_params(struct pw_device_proxy *device, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { - pw_proxy_do((struct pw_proxy*)device, struct pw_device_proxy_methods, enum_params, + return pw_proxy_do((struct pw_proxy*)device, struct pw_device_proxy_methods, enum_params, id, index, num, filter); } -static inline void +static inline int pw_device_proxy_set_param(struct pw_device_proxy *device, uint32_t id, uint32_t flags, const struct spa_pod *param) { - pw_proxy_do((struct pw_proxy*)device, struct pw_device_proxy_methods, set_param, + return pw_proxy_do((struct pw_proxy*)device, struct pw_device_proxy_methods, set_param, id, flags, param); } @@ -505,7 +582,7 @@ struct pw_device_proxy_events { * * \param info info about the device */ - void (*info) (void *object, const struct pw_device_info *info); + int (*info) (void *object, const struct pw_device_info *info); /** * Notify a device param * @@ -516,9 +593,9 @@ struct pw_device_proxy_events { * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, - uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param); + int (*param) (void *object, + uint32_t id, uint32_t index, uint32_t next, + const struct spa_pod *param); }; static inline void @@ -555,7 +632,7 @@ struct pw_node_proxy_methods { * \param num the maximum number of params to retrieve * \param filter a param filter or NULL */ - void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); /** @@ -565,7 +642,7 @@ struct pw_node_proxy_methods { * \param flags extra parameter flags * \param param the parameter to set */ - void (*set_param) (void *object, uint32_t id, uint32_t flags, + int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); /** @@ -573,30 +650,30 @@ struct pw_node_proxy_methods { * * \param command the command to send */ - void (*send_command) (void *object, const struct spa_command *command); + int (*send_command) (void *object, const struct spa_command *command); }; /** Node */ -static inline void +static inline int pw_node_proxy_enum_params(struct pw_node_proxy *node, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { - pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, enum_params, + return pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, enum_params, id, index, num, filter); } -static inline void +static inline int pw_node_proxy_set_param(struct pw_node_proxy *node, uint32_t id, uint32_t flags, const struct spa_pod *param) { - pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, set_param, + return pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, set_param, id, flags, param); } -static inline void +static inline int pw_node_proxy_send_command(struct pw_node_proxy *node, const struct spa_command *command) { - pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, send_command, + return pw_proxy_do((struct pw_proxy*)node, struct pw_node_proxy_methods, send_command, command); } @@ -613,7 +690,7 @@ struct pw_node_proxy_events { * * \param info info about the node */ - void (*info) (void *object, const struct pw_node_info *info); + int (*info) (void *object, const struct pw_node_info *info); /** * Notify a node param * @@ -624,9 +701,9 @@ struct pw_node_proxy_events { * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, - uint32_t id, uint32_t index, uint32_t next, - const struct spa_pod *param); + int (*param) (void *object, + uint32_t id, uint32_t index, uint32_t next, + const struct spa_pod *param); }; static inline void @@ -662,16 +739,16 @@ struct pw_port_proxy_methods { * \param num the maximum number of params to retrieve * \param filter a param filter or NULL */ - void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); }; /** Port params */ -static inline void +static inline int pw_port_proxy_enum_params(struct pw_port_proxy *port, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { - pw_proxy_do((struct pw_proxy*)port, struct pw_port_proxy_methods, enum_params, + return pw_proxy_do((struct pw_proxy*)port, struct pw_port_proxy_methods, enum_params, id, index, num, filter); } @@ -688,7 +765,7 @@ struct pw_port_proxy_events { * * \param info info about the port */ - void (*info) (void *object, const struct pw_port_info *info); + int (*info) (void *object, const struct pw_port_info *info); /** * Notify a port param * @@ -699,7 +776,7 @@ struct pw_port_proxy_events { * \param next the param index of the next param * \param param the parameter */ - void (*param) (void *object, + int (*param) (void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); }; @@ -738,7 +815,7 @@ struct pw_factory_proxy_events { * * \param info info about the factory */ - void (*info) (void *object, const struct pw_factory_info *info); + int (*info) (void *object, const struct pw_factory_info *info); }; /** Factory */ @@ -773,13 +850,13 @@ struct pw_client_proxy_methods { * \param res an errno style error code * \param message an error string */ - void (*error) (void *object, uint32_t id, int res, const char *message); + int (*error) (void *object, uint32_t id, int res, const char *message); /** * Update client properties * * \param props new properties */ - void (*update_properties) (void *object, const struct spa_dict *props); + int (*update_properties) (void *object, const struct spa_dict *props); /** * Get client permissions @@ -789,7 +866,7 @@ struct pw_client_proxy_methods { * \param index the first index to query, 0 for first * \param num the maximum number of items to get */ - void (*get_permissions) (void *object, uint32_t index, uint32_t num); + int (*get_permissions) (void *object, uint32_t index, uint32_t num); /** * Manage the permissions of the global objects for this * client @@ -803,34 +880,34 @@ struct pw_client_proxy_methods { * \param n_permissions number of permissions * \param permissions array of permissions */ - void (*update_permissions) (void *object, uint32_t n_permissions, + int (*update_permissions) (void *object, uint32_t n_permissions, const struct pw_permission *permissions); }; /** Client permissions */ -static inline void +static inline int pw_client_proxy_error(struct pw_client_proxy *client, uint32_t id, int res, const char *message) { - pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, error, id, res, message); + return pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, error, id, res, message); } -static inline void +static inline int pw_client_proxy_update_properties(struct pw_client_proxy *client, const struct spa_dict *props) { - pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, update_properties, props); + return pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, update_properties, props); } -static inline void +static inline int pw_client_proxy_get_permissions(struct pw_client_proxy *client, uint32_t index, uint32_t num) { - pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, get_permissions, index, num); + return pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, get_permissions, index, num); } -static inline void +static inline int pw_client_proxy_update_permissions(struct pw_client_proxy *client, uint32_t n_permissions, const struct pw_permission *permissions) { - pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, update_permissions, + return pw_proxy_do((struct pw_proxy*)client, struct pw_client_proxy_methods, update_permissions, n_permissions, permissions); } @@ -847,7 +924,7 @@ struct pw_client_proxy_events { * * \param info info about the client */ - void (*info) (void *object, const struct pw_client_info *info); + int (*info) (void *object, const struct pw_client_info *info); /** * Notify a client permission * @@ -858,7 +935,7 @@ struct pw_client_proxy_events { * \param n_permissions the number of permissions * \param permissions the permissions */ - void (*permissions) (void *object, + int (*permissions) (void *object, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions); @@ -899,7 +976,7 @@ struct pw_link_proxy_events { * * \param info info about the link */ - void (*info) (void *object, const struct pw_link_info *info); + int (*info) (void *object, const struct pw_link_info *info); }; /** Link */ diff --git a/src/pipewire/link.c b/src/pipewire/link.c index fd3dd4c77..d1b2fb16b 100644 --- a/src/pipewire/link.c +++ b/src/pipewire/link.c @@ -298,9 +298,11 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st asprintf(&error, "error set output format: %d (%s)", res, spa_strerror(res)); goto error; } - if (SPA_RESULT_IS_ASYNC(res)) + if (SPA_RESULT_IS_ASYNC(res)) { + spa_node_sync(output->node->node, res); pw_work_queue_add(impl->work, output->node, res, complete_ready, &this->rt.out_mix); + } } if (in_mix_state == PW_PORT_STATE_CONFIGURE) { pw_log_debug("link %p: doing set format on input mix", this); @@ -312,6 +314,7 @@ static int do_negotiate(struct pw_link *this, uint32_t in_state, uint32_t out_st goto error; } if (SPA_RESULT_IS_ASYNC(res2)) { + spa_node_sync(input->node->node, res2); pw_work_queue_add(impl->work, input->node, res2, complete_ready, &this->rt.in_mix); if (res == 0) @@ -676,9 +679,11 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s asprintf(&error, "error alloc output buffers: %d", res); goto error; } - if (SPA_RESULT_IS_ASYNC(res)) + if (SPA_RESULT_IS_ASYNC(res)) { + spa_node_sync(output->node->node, res); pw_work_queue_add(impl->work, output->node, res, complete_paused, &this->rt.out_mix); + } out_flags &= ~SPA_PORT_FLAG_CAN_USE_BUFFERS; move_allocation(&allocation, &output->allocation); @@ -694,9 +699,11 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s asprintf(&error, "error alloc input buffers: %d", res); goto error; } - if (SPA_RESULT_IS_ASYNC(res)) + if (SPA_RESULT_IS_ASYNC(res)) { + spa_node_sync(input->node->node, res); pw_work_queue_add(impl->work, input->node, res, complete_paused, &this->rt.in_mix); + } in_flags &= ~SPA_PORT_FLAG_CAN_USE_BUFFERS; pw_log_debug("link %p: allocated %d buffers %p from input port", this, @@ -715,9 +722,11 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s spa_strerror(res)); goto error; } - if (SPA_RESULT_IS_ASYNC(res)) + if (SPA_RESULT_IS_ASYNC(res)) { + spa_node_sync(output->node->node, res); pw_work_queue_add(impl->work, output->node, res, complete_paused, &this->rt.out_mix); + } move_allocation(&allocation, &output->allocation); @@ -733,9 +742,11 @@ static int do_allocation(struct pw_link *this, uint32_t in_state, uint32_t out_s spa_strerror(res)); goto error; } - if (SPA_RESULT_IS_ASYNC(res)) + if (SPA_RESULT_IS_ASYNC(res)) { + spa_node_sync(input->node->node, res); pw_work_queue_add(impl->work, input->node, res, complete_paused, &this->rt.in_mix); + } } else { asprintf(&error, "no common buffer alloc found"); diff --git a/src/pipewire/node.c b/src/pipewire/node.c index b4503292f..aa004fd97 100644 --- a/src/pipewire/node.c +++ b/src/pipewire/node.c @@ -60,6 +60,7 @@ struct impl { struct pw_node_activation node_activation; uint32_t next_position; + int last_error; }; struct resource_data { @@ -249,7 +250,7 @@ static int reply_param(void *data, uint32_t id, uint32_t index, uint32_t next, s return 0; } -static void node_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, +static int node_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_resource *resource = object; @@ -264,9 +265,10 @@ static void node_enum_params(void *object, uint32_t id, uint32_t index, uint32_t pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); } + return 0; } -static void node_set_param(void *object, uint32_t id, uint32_t flags, +static int node_set_param(void *object, uint32_t id, uint32_t flags, const struct spa_pod *param) { struct pw_resource *resource = object; @@ -280,9 +282,10 @@ static void node_set_param(void *object, uint32_t id, uint32_t flags, pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); } + return 0; } -static void node_send_command(void *object, const struct spa_command *command) +static int node_send_command(void *object, const struct spa_command *command) { struct pw_resource *resource = object; struct resource_data *data = pw_resource_get_user_data(resource); @@ -296,6 +299,7 @@ static void node_send_command(void *object, const struct spa_command *command) spa_node_send_command(node->node, command); break; } + return 0; } static const struct pw_node_proxy_methods node_methods = { @@ -777,16 +781,17 @@ int pw_node_update_properties(struct pw_node *node, const struct spa_dict *dict) return changed; } -static void node_info(void *data, const struct spa_node_info *info) +static int node_info(void *data, const struct spa_node_info *info) { struct pw_node *node = data; node->info.max_input_ports = info->max_input_ports; node->info.max_output_ports = info->max_output_ports; if (info->change_mask & SPA_NODE_CHANGE_MASK_PROPS) pw_node_update_properties(node, info->props); + return 0; } -static void node_port_info(void *data, enum spa_direction direction, uint32_t port_id, +static int node_port_info(void *data, enum spa_direction direction, uint32_t port_id, const struct spa_port_info *info) { struct pw_node *node = data; @@ -826,27 +831,42 @@ static void node_port_info(void *data, enum spa_direction direction, uint32_t po } } } + return 0; } -static void node_done(void *data, int seq, int res) +static int node_error(void *data, int res, const char *message) { struct pw_node *node = data; struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); - pw_log_debug("node %p: async complete event %d %d %s", node, seq, res, spa_strerror(res)); - pw_work_queue_complete(impl->work, node, seq, res); - pw_node_events_async_complete(node, seq, res); + pw_log_debug("node %p: error event %d: %s", node, res, message); + impl->last_error = res; + node_update_state(node, PW_NODE_STATE_ERROR, strdup(message)); + return 0; } -static void node_event(void *data, struct spa_event *event) +static int node_done(void *data, uint32_t seq) +{ + struct pw_node *node = data; + struct impl *impl = SPA_CONTAINER_OF(node, struct impl, this); + + pw_log_debug("node %p: done event %u", node, seq); + pw_work_queue_complete(impl->work, node, seq, impl->last_error); + pw_node_events_async_complete(node, seq, impl->last_error); + impl->last_error = 0; + return 0; +} + +static int node_event(void *data, struct spa_event *event) { struct pw_node *node = data; pw_log_trace("node %p: event %d", node, SPA_EVENT_TYPE(event)); pw_node_events_event(node, event); + return 0; } -static void node_ready(void *data, int status) +static int node_ready(void *data, int status) { struct pw_node *node = data; struct pw_node *driver = node->driver_node; @@ -855,16 +875,17 @@ static void node_ready(void *data, int status) node->driver, node->exported, driver); if (driver->rt.root.graph == NULL) - return; + return -EINVAL; if (status == SPA_STATUS_HAVE_BUFFER) spa_graph_node_process(&driver->rt.root); spa_graph_run(driver->rt.driver); spa_graph_link_trigger(&driver->rt.driver_link); + return 0; } -static void node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id) +static int node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id) { struct pw_node *node = data; struct spa_graph_port *p, *pp; @@ -877,13 +898,15 @@ static void node_reuse_buffer(void *data, uint32_t port_id, uint32_t buffer_id) spa_graph_node_reuse_buffer(pp->node, pp->port_id, buffer_id); break; } + return 0; } static const struct spa_node_callbacks node_callbacks = { SPA_VERSION_NODE_CALLBACKS, + .done = node_done, + .error = node_error, .info = node_info, .port_info = node_port_info, - .done = node_done, .event = node_event, .ready = node_ready, .reuse_buffer = node_reuse_buffer, @@ -1209,6 +1232,9 @@ int pw_node_set_state(struct pw_node *node, enum pw_node_state state) if (SPA_RESULT_IS_ERROR(res)) return res; + if (SPA_RESULT_IS_ASYNC(res)) + spa_node_sync(node->node, res); + pw_work_queue_add(impl->work, node, res, on_state_complete, SPA_INT_TO_PTR(state)); diff --git a/src/pipewire/port.c b/src/pipewire/port.c index fe1f9344f..59485bbf6 100644 --- a/src/pipewire/port.c +++ b/src/pipewire/port.c @@ -467,7 +467,7 @@ static int reply_param(void *data, uint32_t id, uint32_t index, uint32_t next, s return 0; } -static void port_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, +static int port_enum_params(void *object, uint32_t id, uint32_t index, uint32_t num, const struct spa_pod *filter) { struct pw_resource *resource = object; @@ -479,6 +479,7 @@ static void port_enum_params(void *object, uint32_t id, uint32_t index, uint32_t reply_param, resource)) < 0) pw_core_resource_error(resource->client->core_resource, resource->id, res, spa_strerror(res)); + return res; } static const struct pw_port_proxy_methods port_methods = { diff --git a/src/pipewire/private.h b/src/pipewire/private.h index 8a8bacc63..b9dbadfc8 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -515,6 +515,8 @@ struct pw_link { #define pw_resource_events_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_resource_events, m, v, ##__VA_ARGS__) #define pw_resource_events_destroy(o) pw_resource_events_emit(o, destroy, 0) +#define pw_resource_events_done(o,s) pw_resource_events_emit(o, done, 0, s) +#define pw_resource_events_error(o,e,m) pw_resource_events_emit(o, error, 0, e, m) struct pw_resource { struct pw_core *core; /**< the core object */ @@ -539,6 +541,7 @@ struct pw_resource { #define pw_proxy_events_emit(o,m,v,...) spa_hook_list_call(&o->listener_list, struct pw_proxy_events, m, v, ##__VA_ARGS__) #define pw_proxy_events_destroy(p) pw_proxy_events_emit(p, destroy, 0) +#define pw_proxy_events_done(p,s) pw_proxy_events_emit(p, done, 0, s) #define pw_proxy_events_error(p,r,m) pw_proxy_events_emit(p, error, 0, r, m) struct pw_proxy { diff --git a/src/pipewire/proxy.c b/src/pipewire/proxy.c index 71961cccc..2d311e505 100644 --- a/src/pipewire/proxy.c +++ b/src/pipewire/proxy.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -145,6 +146,27 @@ void pw_proxy_destroy(struct pw_proxy *proxy) free(impl); } +SPA_EXPORT +int pw_proxy_sync(struct pw_proxy *proxy, uint32_t seq) +{ + int res = -EIO; + if (proxy->remote->core_proxy != NULL) + res = pw_core_proxy_sync(proxy->remote->core_proxy, proxy->id, seq); + return res; +} + +SPA_EXPORT +int pw_proxy_error(struct pw_proxy *proxy, int result, const char *error, ...) +{ + va_list ap; + int res = -EIO; + va_start(ap, error); + if (proxy->remote->core_proxy != NULL) + res = pw_core_proxy_errorv(proxy->remote->core_proxy, proxy->id, result, error, ap); + va_end(ap); + return res; +} + SPA_EXPORT struct spa_hook_list *pw_proxy_get_proxy_listeners(struct pw_proxy *proxy) { diff --git a/src/pipewire/proxy.h b/src/pipewire/proxy.h index 4891b9c54..3c6e9a239 100644 --- a/src/pipewire/proxy.h +++ b/src/pipewire/proxy.h @@ -111,6 +111,9 @@ struct pw_proxy_events { /** The proxy is destroyed */ void (*destroy) (void *data); + /** a reply to a sync method completed */ + void (*done) (void *data, uint32_t seq); + /** an error occured on the proxy */ void (*error) (void *data, int res, const char *message); }; @@ -147,6 +150,13 @@ uint32_t pw_proxy_get_id(struct pw_proxy *proxy); /** Get the protocol used for the proxy */ struct pw_protocol *pw_proxy_get_protocol(struct pw_proxy *proxy); +/** Generate an sync method for a proxy. This will generate a done event + * with the same \a seq. */ +int pw_proxy_sync(struct pw_proxy *proxy, uint32_t seq); + +/** Generate an error for a proxy */ +int pw_proxy_error(struct pw_proxy *proxy, int result, const char *error, ...); + /** Get the listener of proxy */ struct spa_hook_list *pw_proxy_get_proxy_listeners(struct pw_proxy *proxy); diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index c8fa02431..ecb156358 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -98,8 +98,27 @@ pw_remote_update_state(struct pw_remote *remote, enum pw_remote_state state, con return 0; } +static int core_event_sync(void *data, uint32_t id, uint32_t seq) +{ + struct pw_remote *this = data; + pw_log_debug("remote %p: object %u sync %u", this, id, seq); + return pw_core_proxy_done(this->core_proxy, id, seq); +} -static void core_event_error(void *data, uint32_t id, int res, const char *message) +static int core_event_done(void *data, uint32_t id, uint32_t seq) +{ + struct pw_remote *this = data; + struct pw_proxy *proxy; + + pw_log_debug("remote %p: object %u done %u", this, id, seq); + + proxy = pw_map_lookup(&this->objects, id); + if (proxy) + pw_proxy_events_done(proxy, seq); + return 0; +} + +static int core_event_error(void *data, uint32_t id, int res, const char *message) { struct pw_remote *this = data; struct pw_proxy *proxy; @@ -110,9 +129,10 @@ static void core_event_error(void *data, uint32_t id, int res, const char *messa proxy = pw_map_lookup(&this->objects, id); if (proxy) pw_proxy_events_error(proxy, res, message); + return 0; } -static void core_event_remove_id(void *data, uint32_t id) +static int core_event_remove_id(void *data, uint32_t id) { struct pw_remote *this = data; struct pw_proxy *proxy; @@ -123,11 +143,14 @@ static void core_event_remove_id(void *data, uint32_t id) pw_proxy_destroy(proxy); pw_map_remove(&this->objects, id); + return 0; } static const struct pw_core_proxy_events core_proxy_events = { PW_VERSION_CORE_PROXY_EVENTS, .error = core_event_error, + .sync = core_event_sync, + .done = core_event_done, .remove_id = core_event_remove_id, }; diff --git a/src/pipewire/resource.c b/src/pipewire/resource.c index 03ae91515..84e7b5b39 100644 --- a/src/pipewire/resource.c +++ b/src/pipewire/resource.c @@ -170,13 +170,24 @@ const struct pw_protocol_marshal *pw_resource_get_marshal(struct pw_resource *re } SPA_EXPORT -void pw_resource_error(struct pw_resource *resource, int result, const char *error, ...) +int pw_resource_sync(struct pw_resource *resource, uint32_t seq) +{ + int res = -EIO; + if (resource->client->core_resource != NULL) + res = pw_core_resource_sync(resource->client->core_resource, resource->id, seq); + return res; +} + +SPA_EXPORT +int pw_resource_error(struct pw_resource *resource, int result, const char *error, ...) { va_list ap; + int res = -EIO; va_start(ap, error); - if (resource->client->core_resource == NULL) - pw_core_resource_errorv(resource->client->core_resource, resource->id, result, error, ap); + if (resource->client->core_resource != NULL) + res = pw_core_resource_errorv(resource->client->core_resource, resource->id, result, error, ap); va_end(ap); + return res; } SPA_EXPORT diff --git a/src/pipewire/resource.h b/src/pipewire/resource.h index c9b4e0bc0..43ded038a 100644 --- a/src/pipewire/resource.h +++ b/src/pipewire/resource.h @@ -67,6 +67,12 @@ struct pw_resource_events { /** The resource is destroyed */ void (*destroy) (void *data); + + /** a reply to a sync event completed */ + void (*done) (void *data, uint32_t seq); + + /** an error occured on the resource */ + void (*error) (void *data, int res, const char *message); }; /** Make a new resource for client */ @@ -116,8 +122,12 @@ void pw_resource_add_override(struct pw_resource *resource, const void *implementation, void *data); +/** Generate an sync method for a resource. This will generate a done event + * with the same \a seq. */ +int pw_resource_sync(struct pw_resource *resource, uint32_t seq); + /** Generate an error for a resource */ -void pw_resource_error(struct pw_resource *resource, int result, const char *error, ...); +int pw_resource_error(struct pw_resource *resource, int result, const char *error, ...); /** Get the implementation list of a resource */ struct spa_hook_list *pw_resource_get_implementation(struct pw_resource *resource); diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index da9fb1c88..e7d7af3a1 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -452,6 +452,9 @@ static int port_set_format(struct spa_node *node, if (count == 0) pw_stream_finish_format(stream, 0, NULL, 0); + if (stream->state == PW_STREAM_STATE_ERROR) + return -EIO; + stream_set_state(stream, p ? PW_STREAM_STATE_READY : @@ -772,9 +775,16 @@ static void proxy_destroy(void *_data) stream_set_state(stream, PW_STREAM_STATE_UNCONNECTED, NULL); } +static void proxy_error(void *_data, int res, const char *message) +{ + struct pw_stream *stream = _data; + stream_set_state(stream, PW_STREAM_STATE_ERROR, message); +} + static const struct pw_proxy_events proxy_events = { PW_VERSION_PROXY_EVENTS, .destroy = proxy_destroy, + .error = proxy_error, }; static int handle_connect(struct pw_stream *stream) @@ -1174,6 +1184,12 @@ void pw_stream_finish_format(struct pw_stream *stream, pw_log_debug("stream %p: finish format %d %d", stream, res, impl->pending_seq); + if (res < 0) { + pw_proxy_error(stream->proxy, res, "format failed"); + stream_set_state(stream, PW_STREAM_STATE_ERROR, "format error"); + return; + } + clear_params(stream, PARAM_TYPE_OTHER); for (i = 0; i < n_params; i++) add_param(stream, PARAM_TYPE_OTHER, params[i]); diff --git a/src/tests/test-interfaces.c b/src/tests/test-interfaces.c index 346c8bccd..50325a964 100644 --- a/src/tests/test-interfaces.c +++ b/src/tests/test-interfaces.c @@ -37,28 +37,33 @@ static void test_core_abi(void) struct pw_core_proxy_events e; struct { uint32_t version; - void (*hello) (void *object, uint32_t version); - void (*sync) (void *object, uint32_t seq); - void (*get_registry) (void *object, uint32_t version, uint32_t new_id); - void (*create_object) (void *object, + int (*hello) (void *object, uint32_t version); + int (*sync) (void *object, uint32_t id, uint32_t seq); + int (*done) (void *object, uint32_t id, uint32_t seq); + int (*error) (void *object, uint32_t id, int res, const char *error); + int (*get_registry) (void *object, uint32_t version, uint32_t new_id); + int (*create_object) (void *object, const char *factory_name, uint32_t type, uint32_t version, const struct spa_dict *props, uint32_t new_id); - void (*destroy) (void *object, uint32_t id); + int (*destroy) (void *object, uint32_t id); } methods = { PW_VERSION_CORE_PROXY_METHODS, }; struct { uint32_t version; - void (*done) (void *object, uint32_t seq); - void (*error) (void *object, uint32_t id, int res, const char *error); - void (*remove_id) (void *object, uint32_t id); - void (*info) (void *object, const struct pw_core_info *info); + int (*info) (void *object, const struct pw_core_info *info); + int (*done) (void *object, uint32_t id, uint32_t seq); + int (*sync) (void *object, uint32_t id, uint32_t seq); + int (*error) (void *object, uint32_t id, int res, const char *error); + int (*remove_id) (void *object, uint32_t id); } events = { PW_VERSION_CORE_PROXY_EVENTS, }; TEST_FUNC(m, methods, version); TEST_FUNC(m, methods, hello); TEST_FUNC(m, methods, sync); + TEST_FUNC(m, methods, done); + TEST_FUNC(e, methods, error); TEST_FUNC(m, methods, get_registry); TEST_FUNC(m, methods, create_object); TEST_FUNC(m, methods, destroy); @@ -66,10 +71,11 @@ static void test_core_abi(void) spa_assert(sizeof(m) == sizeof(methods)); TEST_FUNC(e, events, version); + TEST_FUNC(e, events, info); TEST_FUNC(e, events, done); + TEST_FUNC(e, events, sync); TEST_FUNC(e, events, error); TEST_FUNC(e, events, remove_id); - TEST_FUNC(e, events, info); spa_assert(PW_VERSION_CORE_PROXY_EVENTS == 0); spa_assert(sizeof(e) == sizeof(events)); } @@ -80,15 +86,15 @@ static void test_registry_abi(void) struct pw_registry_proxy_events e; struct { uint32_t version; - void (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id); - void (*destroy) (void *object, uint32_t id); + int (*bind) (void *object, uint32_t id, uint32_t type, uint32_t version, uint32_t new_id); + int (*destroy) (void *object, uint32_t id); } methods = { PW_VERSION_REGISTRY_PROXY_METHODS, }; struct { uint32_t version; - void (*global) (void *object, uint32_t id, uint32_t parent_id, + int (*global) (void *object, uint32_t id, uint32_t parent_id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props); - void (*global_remove) (void *object, uint32_t id); + int (*global_remove) (void *object, uint32_t id); } events = { PW_VERSION_REGISTRY_PROXY_EVENTS, }; TEST_FUNC(m, methods, version); @@ -113,7 +119,7 @@ static void test_module_abi(void) } methods = { PW_VERSION_MODULE_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_module_info *info); + int (*info) (void *object, const struct pw_module_info *info); } events = { PW_VERSION_MODULE_PROXY_EVENTS, }; TEST_FUNC(m, methods, version); @@ -132,15 +138,15 @@ static void test_device_abi(void) struct pw_device_proxy_events e; struct { uint32_t version; - void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); - void (*set_param) (void *object, uint32_t id, uint32_t flags, + int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); } methods = { PW_VERSION_DEVICE_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_device_info *info); - void (*param) (void *object, + int (*info) (void *object, const struct pw_device_info *info); + int (*param) (void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_DEVICE_PROXY_EVENTS, }; @@ -164,16 +170,16 @@ static void test_node_abi(void) struct pw_node_proxy_events e; struct { uint32_t version; - void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); - void (*set_param) (void *object, uint32_t id, uint32_t flags, + int (*set_param) (void *object, uint32_t id, uint32_t flags, const struct spa_pod *param); - void (*send_command) (void *object, const struct spa_command *command); + int (*send_command) (void *object, const struct spa_command *command); } methods = { PW_VERSION_NODE_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_node_info *info); - void (*param) (void *object, + int (*info) (void *object, const struct pw_node_info *info); + int (*param) (void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_NODE_PROXY_EVENTS, }; @@ -198,13 +204,13 @@ static void test_port_abi(void) struct pw_port_proxy_events e; struct { uint32_t version; - void (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, + int (*enum_params) (void *object, uint32_t id, uint32_t start, uint32_t num, const struct spa_pod *filter); } methods = { PW_VERSION_PORT_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_port_info *info); - void (*param) (void *object, + int (*info) (void *object, const struct pw_port_info *info); + int (*param) (void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param); } events = { PW_VERSION_PORT_PROXY_EVENTS, }; @@ -230,7 +236,7 @@ static void test_factory_abi(void) } methods = { PW_VERSION_FACTORY_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_factory_info *info); + int (*info) (void *object, const struct pw_factory_info *info); } events = { PW_VERSION_FACTORY_PROXY_EVENTS, }; TEST_FUNC(m, methods, version); @@ -249,16 +255,16 @@ static void test_client_abi(void) struct pw_client_proxy_events e; struct { uint32_t version; - void (*error) (void *object, uint32_t id, int res, const char *error); - void (*update_properties) (void *object, const struct spa_dict *props); - void (*get_permissions) (void *object, uint32_t index, uint32_t num); - void (*update_permissions) (void *object, uint32_t n_permissions, + int (*error) (void *object, uint32_t id, int res, const char *error); + int (*update_properties) (void *object, const struct spa_dict *props); + int (*get_permissions) (void *object, uint32_t index, uint32_t num); + int (*update_permissions) (void *object, uint32_t n_permissions, const struct pw_permission *permissions); } methods = { PW_VERSION_CLIENT_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_client_info *info); - void (*permissions) (void *object, uint32_t index, + int (*info) (void *object, const struct pw_client_info *info); + int (*permissions) (void *object, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions); } events = { PW_VERSION_CLIENT_PROXY_EVENTS, }; @@ -285,7 +291,7 @@ static void test_link_abi(void) } methods = { PW_VERSION_LINK_PROXY_METHODS, }; struct { uint32_t version; - void (*info) (void *object, const struct pw_link_info *info); + int (*info) (void *object, const struct pw_link_info *info); } events = { PW_VERSION_LINK_PROXY_EVENTS, }; TEST_FUNC(m, methods, version); diff --git a/src/tools/pipewire-cli.c b/src/tools/pipewire-cli.c index 0c679958e..2bcbfb37c 100644 --- a/src/tools/pipewire-cli.c +++ b/src/tools/pipewire-cli.c @@ -242,12 +242,13 @@ static bool do_load_module(struct data *data, const char *cmd, char *args, char return true; } -static void on_core_info(void *_data, const struct pw_core_info *info) +static int on_core_info(void *_data, const struct pw_core_info *info) { struct remote_data *rd = _data; free(rd->name); rd->name = strdup(info->name); fprintf(stdout, "remote %d is named '%s'\n", rd->id, rd->name); + return 0; } static void show_prompt(struct remote_data *rd) @@ -256,7 +257,7 @@ static void show_prompt(struct remote_data *rd) fflush(stdout); } -static void on_core_done(void *_data, uint32_t seq) +static int on_core_done(void *_data, uint32_t id, uint32_t seq) { struct remote_data *rd = _data; @@ -267,6 +268,7 @@ static void on_core_done(void *_data, uint32_t seq) default: break; } + return 0; } static int print_global(void *obj, void *data) @@ -285,9 +287,9 @@ static int print_global(void *obj, void *data) return 0; } -static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, - uint32_t permissions, uint32_t type, uint32_t version, - const struct spa_dict *props) +static int registry_event_global(void *data, uint32_t id, uint32_t parent_id, + uint32_t permissions, uint32_t type, uint32_t version, + const struct spa_dict *props) { struct remote_data *rd = data; struct global *global; @@ -309,6 +311,7 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, while (id > size) pw_map_insert_at(&rd->globals, size++, NULL); pw_map_insert_at(&rd->globals, id, global); + return 0; } static int destroy_global(void *obj, void *data) @@ -325,7 +328,7 @@ static int destroy_global(void *obj, void *data) return 0; } -static void registry_event_global_remove(void *data, uint32_t id) +static int registry_event_global_remove(void *data, uint32_t id) { struct remote_data *rd = data; struct global *global; @@ -333,12 +336,13 @@ static void registry_event_global_remove(void *data, uint32_t id) global = pw_map_lookup(&rd->globals, id); if (global == NULL) { fprintf(stdout, "remote %d removed unknown global %d\n", rd->id, id); - return; + return -EINVAL; } fprintf(stdout, "remote %d removed global: ", rd->id); print_global(global, NULL); destroy_global(global, rd); + return 0; } static const struct pw_registry_proxy_events registry_events = { @@ -392,7 +396,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, pw_registry_proxy_add_listener(rd->registry_proxy, &rd->registry_listener, ®istry_events, rd); - pw_core_proxy_sync(rd->core_proxy, 1); + pw_core_proxy_sync(rd->core_proxy, 0, 1); break; default: @@ -627,7 +631,7 @@ static void info_device(struct proxy_data *pd) info->change_mask = 0; } -static void core_event_info(void *object, const struct pw_core_info *info) +static int core_event_info(void *object, const struct pw_core_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -640,6 +644,7 @@ static void core_event_info(void *object, const struct pw_core_info *info) info_core(pd); pd->global->info_pending = false; } + return 0; } static const struct pw_core_proxy_events core_events = { @@ -648,7 +653,7 @@ static const struct pw_core_proxy_events core_events = { }; -static void module_event_info(void *object, const struct pw_module_info *info) +static int module_event_info(void *object, const struct pw_module_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -661,6 +666,7 @@ static void module_event_info(void *object, const struct pw_module_info *info) info_module(pd); pd->global->info_pending = false; } + return 0; } static const struct pw_module_proxy_events module_events = { @@ -668,7 +674,7 @@ static const struct pw_module_proxy_events module_events = { .info = module_event_info }; -static void node_event_info(void *object, const struct pw_node_info *info) +static int node_event_info(void *object, const struct pw_node_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -681,9 +687,10 @@ static void node_event_info(void *object, const struct pw_node_info *info) info_node(pd); pd->global->info_pending = false; } + return 0; } -static void node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; @@ -696,6 +703,7 @@ static void node_event_param(void *object, uint32_t id, uint32_t index, uint32_t spa_debug_format(2, NULL, param); else spa_debug_pod(2, NULL, param); + return 0; } static const struct pw_node_proxy_events node_events = { @@ -705,7 +713,7 @@ static const struct pw_node_proxy_events node_events = { }; -static void port_event_info(void *object, const struct pw_port_info *info) +static int port_event_info(void *object, const struct pw_port_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -718,9 +726,10 @@ static void port_event_info(void *object, const struct pw_port_info *info) info_port(pd); pd->global->info_pending = false; } + return 0; } -static void port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; @@ -733,6 +742,7 @@ static void port_event_param(void *object, uint32_t id, uint32_t index, uint32_t spa_debug_format(2, NULL, param); else spa_debug_pod(2, NULL, param); + return 0; } static const struct pw_port_proxy_events port_events = { @@ -741,7 +751,7 @@ static const struct pw_port_proxy_events port_events = { .param = port_event_param }; -static void factory_event_info(void *object, const struct pw_factory_info *info) +static int factory_event_info(void *object, const struct pw_factory_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -754,6 +764,7 @@ static void factory_event_info(void *object, const struct pw_factory_info *info) info_factory(pd); pd->global->info_pending = false; } + return 0; } static const struct pw_factory_proxy_events factory_events = { @@ -761,7 +772,7 @@ static const struct pw_factory_proxy_events factory_events = { .info = factory_event_info }; -static void client_event_info(void *object, const struct pw_client_info *info) +static int client_event_info(void *object, const struct pw_client_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -774,9 +785,10 @@ static void client_event_info(void *object, const struct pw_client_info *info) info_client(pd); pd->global->info_pending = false; } + return 0; } -static void client_event_permissions(void *object, uint32_t index, +static int client_event_permissions(void *object, uint32_t index, uint32_t n_permissions, const struct pw_permission *permissions) { struct proxy_data *data = object; @@ -793,6 +805,7 @@ static void client_event_permissions(void *object, uint32_t index, fprintf(stdout, " %u:", permissions[i].id); fprintf(stdout, " %08x\n", permissions[i].permissions); } + return 0; } static const struct pw_client_proxy_events client_events = { @@ -801,7 +814,7 @@ static const struct pw_client_proxy_events client_events = { .permissions = client_event_permissions }; -static void link_event_info(void *object, const struct pw_link_info *info) +static int link_event_info(void *object, const struct pw_link_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -814,6 +827,7 @@ static void link_event_info(void *object, const struct pw_link_info *info) info_link(pd); pd->global->info_pending = false; } + return 0; } static const struct pw_link_proxy_events link_events = { @@ -822,7 +836,7 @@ static const struct pw_link_proxy_events link_events = { }; -static void device_event_info(void *object, const struct pw_device_info *info) +static int device_event_info(void *object, const struct pw_device_info *info) { struct proxy_data *pd = object; struct remote_data *rd = pd->rd; @@ -835,6 +849,7 @@ static void device_event_info(void *object, const struct pw_device_info *info) info_device(pd); pd->global->info_pending = false; } + return 0; } static const struct pw_device_proxy_events device_events = { @@ -1375,7 +1390,7 @@ static void do_input(void *data, int fd, enum spa_io mask) if (d->current == NULL) pw_main_loop_quit(d->loop); else if (d->current->core_proxy) - pw_core_proxy_sync(d->current->core_proxy, 1); + pw_core_proxy_sync(d->current->core_proxy, 0, 1); } } diff --git a/src/tools/pipewire-monitor.c b/src/tools/pipewire-monitor.c index 170423bee..d1acb12cb 100644 --- a/src/tools/pipewire-monitor.c +++ b/src/tools/pipewire-monitor.c @@ -82,7 +82,7 @@ static void add_pending(struct proxy_data *pd) spa_list_append(&d->pending_list, &pd->pending_link); pd->pending_seq = ++d->seq; - pw_core_proxy_sync(d->core_proxy, pd->pending_seq); + pw_core_proxy_sync(d->core_proxy, 0, pd->pending_seq); } static void remove_pending(struct proxy_data *pd) @@ -93,7 +93,7 @@ static void remove_pending(struct proxy_data *pd) } } -static void on_core_done(void *data, uint32_t seq) +static int on_core_done(void *data, uint32_t id, uint32_t seq) { struct data *d = data; struct proxy_data *pd, *t; @@ -104,6 +104,7 @@ static void on_core_done(void *data, uint32_t seq) pd->print_func(pd); } } + return 0; } static void clear_params(struct proxy_data *data) @@ -118,12 +119,15 @@ static void clear_params(struct proxy_data *data) data->params = NULL; } -static void add_param(struct proxy_data *data, const struct spa_pod *param) +static int add_param(struct proxy_data *data, const struct spa_pod *param) { uint32_t idx = data->n_params++; data->params = realloc(data->params, sizeof(struct spa_pod *) * data->n_params); + if (data->params == NULL) + return -ENOMEM; data->params[idx] = pw_spa_pod_copy(param); + return 0; } static void print_properties(const struct spa_dict *props, char mark) @@ -146,7 +150,7 @@ static void print_properties(const struct spa_dict *props, char mark) #define MARK_CHANGE(f) ((print_mark && ((info)->change_mask & (1 << (f)))) ? '*' : ' ') -static void on_core_info(void *data, const struct pw_core_info *info) +static int on_core_info(void *data, const struct pw_core_info *info) { bool print_all = true, print_mark = false; @@ -159,9 +163,10 @@ static void on_core_info(void *data, const struct pw_core_info *info) printf("%c\tname: \"%s\"\n", MARK_CHANGE(3), info->name); print_properties(info->props, MARK_CHANGE(4)); } + return 0; } -static void module_event_info(void *object, const struct pw_module_info *info) +static int module_event_info(void *object, const struct pw_module_info *info) { struct proxy_data *data = object; bool print_all, print_mark; @@ -191,6 +196,7 @@ static void module_event_info(void *object, const struct pw_module_info *info) printf("%c\targs: \"%s\"\n", MARK_CHANGE(2), info->args); print_properties(info->props, MARK_CHANGE(3)); } + return 0; } static const struct pw_module_proxy_events module_events = { @@ -247,7 +253,7 @@ static void print_node(struct proxy_data *data) } } -static void node_event_info(void *object, const struct pw_node_info *info) +static int node_event_info(void *object, const struct pw_node_info *info) { struct proxy_data *data = object; bool is_new = data->info == NULL; @@ -261,13 +267,14 @@ static void node_event_info(void *object, const struct pw_node_info *info) } if (data->pending_seq == SPA_ID_INVALID) data->print_func(data); + return 0; } -static void node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int node_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; - add_param(data, param); + return add_param(data, param); } static const struct pw_node_proxy_events node_events = { @@ -313,7 +320,7 @@ static void print_port(struct proxy_data *data) } } -static void port_event_info(void *object, const struct pw_port_info *info) +static int port_event_info(void *object, const struct pw_port_info *info) { struct proxy_data *data = object; @@ -328,13 +335,14 @@ static void port_event_info(void *object, const struct pw_port_info *info) } if (data->pending_seq == SPA_ID_INVALID) data->print_func(data); + return 0; } -static void port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, +static int port_event_param(void *object, uint32_t id, uint32_t index, uint32_t next, const struct spa_pod *param) { struct proxy_data *data = object; - add_param(data, param); + return add_param(data, param); } static const struct pw_port_proxy_events port_events = { @@ -343,7 +351,7 @@ static const struct pw_port_proxy_events port_events = { .param = port_event_param }; -static void factory_event_info(void *object, const struct pw_factory_info *info) +static int factory_event_info(void *object, const struct pw_factory_info *info) { struct proxy_data *data = object; bool print_all, print_mark; @@ -372,6 +380,7 @@ static void factory_event_info(void *object, const struct pw_factory_info *info) if (print_all) { print_properties(info->props, MARK_CHANGE(0)); } + return 0; } static const struct pw_factory_proxy_events factory_events = { @@ -379,7 +388,7 @@ static const struct pw_factory_proxy_events factory_events = { .info = factory_event_info }; -static void client_event_info(void *object, const struct pw_client_info *info) +static int client_event_info(void *object, const struct pw_client_info *info) { struct proxy_data *data = object; bool print_all, print_mark; @@ -406,6 +415,7 @@ static void client_event_info(void *object, const struct pw_client_info *info) if (print_all) { print_properties(info->props, MARK_CHANGE(0)); } + return 0; } static const struct pw_client_proxy_events client_events = { @@ -413,7 +423,7 @@ static const struct pw_client_proxy_events client_events = { .info = client_event_info }; -static void link_event_info(void *object, const struct pw_link_info *info) +static int link_event_info(void *object, const struct pw_link_info *info) { struct proxy_data *data = object; bool print_all, print_mark; @@ -454,6 +464,7 @@ static void link_event_info(void *object, const struct pw_link_info *info) printf("\t\tnone\n"); print_properties(info->props, MARK_CHANGE(4)); } + return 0; } static const struct pw_link_proxy_events link_events = { @@ -461,9 +472,7 @@ static const struct pw_link_proxy_events link_events = { .info = link_event_info }; - - -static void device_event_info(void *object, const struct pw_device_info *info) +static int device_event_info(void *object, const struct pw_device_info *info) { struct proxy_data *data = object; bool print_all, print_mark; @@ -490,6 +499,7 @@ static void device_event_info(void *object, const struct pw_device_info *info) if (print_all) { print_properties(info->props, MARK_CHANGE(0)); } + return 0; } static const struct pw_device_proxy_events device_events = { @@ -518,7 +528,7 @@ static const struct pw_proxy_events proxy_events = { .destroy = destroy_proxy, }; -static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, +static int registry_event_global(void *data, uint32_t id, uint32_t parent_id, uint32_t permissions, uint32_t type, uint32_t version, const struct spa_dict *props) { @@ -577,7 +587,7 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, permissions & PW_PERM_X ? 'x' : '-'); printf("\ttype: %s (version %d)\n", spa_debug_type_find_name(pw_type_info(), type), version); print_properties(props, ' '); - return; + return 0; } proxy = pw_registry_proxy_bind(d->registry_proxy, id, type, @@ -600,18 +610,18 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id, pd->print_func = print_func; pw_proxy_add_proxy_listener(proxy, &pd->proxy_proxy_listener, events, pd); pw_proxy_add_listener(proxy, &pd->proxy_listener, &proxy_events, pd); - - return; + return 0; no_mem: printf("failed to create proxy"); - return; + return -ENOMEM; } -static void registry_event_global_remove(void *object, uint32_t id) +static int registry_event_global_remove(void *object, uint32_t id) { printf("removed:\n"); printf("\tid: %u\n", id); + return 0; } static const struct pw_registry_proxy_events registry_events = {