improve error handling some more

This commit is contained in:
Wim Taymans 2019-06-20 11:04:34 +02:00
parent d1241e2c1c
commit a212d2f9ed
30 changed files with 393 additions and 312 deletions

View file

@ -170,24 +170,22 @@ core_check_access(void *data, struct pw_client *client)
goto wait_permissions;
}
granted:
granted:
pw_log_debug("module %p: client %p access granted", impl, client);
permissions[0] = PW_PERMISSION_INIT(-1, PW_PERM_RWX);
pw_client_update_permissions(client, 1, permissions);
return;
wait_permissions:
wait_permissions:
pw_log_debug("module %p: client %p wait for permissions", impl, client);
pw_client_update_properties(client, &SPA_DICT_INIT(items, 1));
pw_client_set_busy(client, true);
return;
blacklisted:
blacklisted:
pw_resource_error(pw_client_get_core_resource(client), res, "blacklisted");
pw_client_update_properties(client, &SPA_DICT_INIT(items, 1));
return;
}
static const struct pw_core_events core_events = {

View file

@ -47,7 +47,6 @@ static const struct spa_dict_item module_props[] = {
struct factory_data {
struct pw_factory *this;
struct pw_properties *properties;
struct spa_list node_list;
@ -103,19 +102,20 @@ static void *create_object(void *_data,
struct pw_resource *bound_resource;
if (resource == NULL)
goto no_resource;
goto error_resource;
client = pw_resource_get_client(resource);
dsp = pw_audio_dsp_new(pw_module_get_core(d->module),
properties,
sizeof(struct node_data));
properties = NULL;
if (dsp == NULL) {
if (errno == ENOMEM)
goto no_mem;
goto error_no_mem;
else
goto usage;
goto error_usage;
}
nd = pw_audio_dsp_get_user_data(dsp);
@ -129,38 +129,39 @@ static void *create_object(void *_data,
res = pw_global_bind(pw_node_get_global(dsp), client,
PW_PERM_RWX, PW_VERSION_NODE_PROXY, new_id);
if (res < 0)
goto no_bind;
goto error_bind;
if ((bound_resource = pw_client_find_resource(client, new_id)) == NULL)
goto no_bind;
goto error_bind;
pw_resource_add_listener(bound_resource, &nd->resource_listener, &resource_events, nd);
pw_node_set_active(dsp, true);
if (properties)
pw_properties_free(properties);
return dsp;
no_resource:
error_resource:
res = -EINVAL;
pw_log_error("audio-dsp needs a resource");
pw_resource_error(resource, -EINVAL, "no resource");
goto done;
usage:
pw_resource_error(resource, res, "no resource");
goto error_cleanup;
error_no_mem:
res = -errno;
pw_log_error("can't create node: %m");
pw_resource_error(resource, res, "no memory");
goto error_cleanup;
error_usage:
res = -EINVAL;
pw_log_error("usage: "AUDIO_DSP_USAGE);
pw_resource_error(resource, -EINVAL, "usage: "AUDIO_DSP_USAGE);
goto done;
no_mem:
pw_log_error("can't create node");
pw_resource_error(resource, -ENOMEM, "no memory");
goto done;
no_bind:
pw_resource_error(resource, res, "usage: "AUDIO_DSP_USAGE);
goto error_cleanup;
error_bind:
pw_resource_error(resource, res, "can't bind dsp node");
goto done;
done:
goto error_cleanup;
error_cleanup:
if (properties)
pw_properties_free(properties);
errno = -res;
return NULL;
}
@ -179,9 +180,6 @@ static void module_destroy(void *data)
spa_list_for_each_safe(nd, t, &d->node_list, link)
pw_node_destroy(nd->dsp);
if (d->properties)
pw_properties_free(d->properties);
pw_factory_destroy(d->this);
}
@ -210,7 +208,6 @@ static int module_init(struct pw_module *module, struct pw_properties *propertie
data = pw_factory_get_user_data(factory);
data->this = factory;
data->module = module;
data->properties = properties;
spa_list_init(&data->node_list);
pw_log_debug("module %p: new", module);

View file

@ -257,37 +257,34 @@ static const struct pw_node_events node_events = {
};
struct pw_node *pw_audio_dsp_new(struct pw_core *core,
const struct pw_properties *props,
struct pw_properties *props,
size_t user_data_size)
{
struct pw_node *node;
struct node *n;
const char *api, *alias, *str, *factory;
char node_name[128];
struct pw_properties *pr;
enum pw_direction direction;
uint32_t max_buffer_size;
int i;
int i, res = -ENOENT;
pr = pw_properties_copy(props);
if ((str = pw_properties_get(pr, "audio-dsp.direction")) == NULL) {
if ((str = pw_properties_get(props, "audio-dsp.direction")) == NULL) {
pw_log_error("missing audio-dsp.direction property");
goto error;
}
direction = pw_properties_parse_int(str);
if ((str = pw_properties_get(pr, "audio-dsp.maxbuffer")) == NULL) {
if ((str = pw_properties_get(props, "audio-dsp.maxbuffer")) == NULL) {
pw_log_error("missing audio-dsp.maxbuffer property");
goto error;
}
max_buffer_size = pw_properties_parse_int(str);
if ((api = pw_properties_get(pr, PW_KEY_DEVICE_API)) == NULL) {
if ((api = pw_properties_get(props, PW_KEY_DEVICE_API)) == NULL) {
pw_log_error("missing "PW_KEY_DEVICE_API" property");
goto error;
}
if ((alias = pw_properties_get(pr, "audio-dsp.name")) == NULL) {
if ((alias = pw_properties_get(props, "audio-dsp.name")) == NULL) {
pw_log_error("missing audio-dsp.name property");
goto error;
}
@ -298,34 +295,36 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
node_name[i] = '_';
}
pw_properties_set(pr,
pw_properties_set(props,
PW_KEY_MEDIA_CLASS,
direction == PW_DIRECTION_OUTPUT ?
"Audio/DSP/Playback" :
"Audio/DSP/Capture");
pw_properties_set(pr, PW_KEY_NODE_DRIVER, NULL);
pw_properties_set(props, PW_KEY_NODE_DRIVER, NULL);
if ((str = pw_properties_get(pr, PW_KEY_NODE_ID)) != NULL)
pw_properties_set(pr, PW_KEY_NODE_SESSION, str);
if ((str = pw_properties_get(props, PW_KEY_NODE_ID)) != NULL)
pw_properties_set(props, PW_KEY_NODE_SESSION, str);
if (direction == PW_DIRECTION_OUTPUT) {
pw_properties_set(pr, "merger.monitor", "1");
pw_properties_set(props, "merger.monitor", "1");
factory = "merge";
} else {
factory = "split";
}
pw_properties_set(pr, "factory.mode", factory);
pw_properties_set(props, "factory.mode", factory);
factory = "audioconvert";
pw_properties_set(pr, SPA_KEY_LIBRARY_NAME, "audioconvert/libspa-audioconvert");
pw_properties_set(props, SPA_KEY_LIBRARY_NAME, "audioconvert/libspa-audioconvert");
node = pw_spa_node_load(core, NULL, NULL,
factory,
node_name,
PW_SPA_NODE_FLAG_ACTIVATE | PW_SPA_NODE_FLAG_NO_REGISTER,
pr, sizeof(struct node) + user_data_size);
pw_properties_copy(props),
sizeof(struct node) + user_data_size);
if (node == NULL) {
pw_log_error("can't load spa node");
res = -errno;
pw_log_error("can't load spa node: %m");
goto error;
}
@ -333,7 +332,7 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
n->core = core;
n->node = node;
n->direction = direction;
n->props = pw_properties_copy(pr);
n->props = props;
spa_list_init(&n->ports);
n->max_buffer_size = max_buffer_size;
@ -345,8 +344,10 @@ struct pw_node *pw_audio_dsp_new(struct pw_core *core,
return node;
error:
pw_properties_free(pr);
error:
if (props)
pw_properties_free(props);
errno = -res;
return NULL;
}

View file

@ -40,7 +40,7 @@ extern "C" {
struct pw_node *
pw_audio_dsp_new(struct pw_core *core,
const struct pw_properties *properties,
struct pw_properties *properties,
size_t user_data_size);
void *pw_audio_dsp_get_user_data(struct pw_node *node);

View file

@ -346,7 +346,7 @@ impl_node_port_enum_params(void *object, int seq,
result.id = id;
result.next = start;
next:
next:
result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer));

View file

@ -99,6 +99,7 @@ error_node:
pw_log_error("can't create node: %s", spa_strerror(res));
pw_resource_error(resource, res, "can't create node: %s", spa_strerror(res));
goto error_exit_free;
error_exit_free:
pw_resource_destroy(node_resource);
error_exit:

View file

@ -244,7 +244,7 @@ static struct mem *ensure_mem(struct impl *impl, int fd, uint32_t type, uint32_t
type,
m->fd,
m->flags);
found:
found:
m->ref++;
pw_log_debug("client-node %p: mem %d, ref %d", impl, m->id, m->ref);
return m;
@ -328,7 +328,7 @@ static struct io *update_io(struct node *this,
spa_log_debug(this->log, "node %p: add io %p %s %d", this, io,
spa_debug_type_find_name(spa_type_io, id), memid);
found:
found:
return io;
}
@ -1680,10 +1680,13 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
const struct spa_support *support;
uint32_t n_support;
const char *name;
int res;
impl = calloc(1, sizeof(struct impl));
if (impl == NULL)
return NULL;
if (impl == NULL) {
res = -errno;
goto error_exit_cleanup;
}
this = &impl->this;
@ -1714,6 +1717,7 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
(struct spa_node *)&impl->node.node,
NULL,
properties, 0);
if (this->node == NULL)
goto error_no_node;
@ -1738,10 +1742,20 @@ struct pw_client_node *pw_client_node_new(struct pw_resource *resource,
return this;
error_no_node:
pw_resource_destroy(this->resource);
error_no_node:
res = -errno;
node_clear(&impl->node);
properties = NULL;
goto error_exit_free;
error_exit_free:
free(impl);
error_exit_cleanup:
if (resource)
pw_resource_destroy(resource);
if (properties)
pw_properties_free(properties);
errno = -res;
return NULL;
}

View file

@ -136,7 +136,7 @@ static int impl_node_enum_params(void *object, int seq,
result.id = id;
result.next = start;
next:
next:
result.index = result.next++;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
@ -1252,10 +1252,13 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
struct pw_properties *props;
uint32_t n_support;
const char *name;
int res;
impl = calloc(1, sizeof(struct impl));
if (impl == NULL)
return NULL;
if (impl == NULL) {
res = -errno;
goto error_exit_cleanup;
}
this = &impl->this;
@ -1271,8 +1274,11 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
parent,
props,
false);
if (impl->client_node == NULL)
goto error_no_node;
resource = NULL;
if (impl->client_node == NULL) {
res = -errno;
goto error_exit_free;
}
impl->cnode = pw_node_get_implementation(impl->client_node->node);
spa_node_set_callbacks(impl->cnode, &node_callbacks, impl);
@ -1293,8 +1299,11 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
(struct spa_node *)&impl->node.node,
NULL,
properties, 0);
if (this->node == NULL)
goto error_no_node;
properties = NULL;
if (this->node == NULL) {
res = -errno;
goto error_exit_free_client_node;
}
this->node->remote = true;
@ -1305,9 +1314,16 @@ struct pw_client_stream *pw_client_stream_new(struct pw_resource *resource,
return this;
error_no_node:
pw_resource_destroy(resource);
error_exit_free_client_node:
pw_client_node_destroy(impl->client_node);
error_exit_free:
free(impl);
error_exit_cleanup:
if (resource)
pw_resource_destroy(resource);
if (properties)
pw_properties_free(properties);
errno = -res;
return NULL;
}

View file

@ -656,9 +656,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 %s port %d",
direction == SPA_DIRECTION_INPUT ? "input" : "output", port_id);
goto done;
goto error_exit;
}
pw_log_debug("port %p: set param %d %p", port, id, param);
@ -672,12 +670,14 @@ client_node_port_set_param(void *object,
}
res = pw_port_set_param(port, id, flags, param);
if (res < 0) {
pw_proxy_error(proxy, res, "can't set port param: %s", spa_strerror(res));
goto done;
}
if (res < 0)
goto error_exit;
done:
return res;
error_exit:
pw_log_error("port %p: set_param %d %p: %s", port, id, param, spa_strerror(res));
pw_proxy_error(proxy, res, "port_set_param: %s", spa_strerror(res));
return res;
}
@ -696,9 +696,8 @@ 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;
res = -ENOENT;
goto error_exit;
}
prot = PROT_READ | (direction == SPA_DIRECTION_OUTPUT ? PROT_WRITE : 0);
@ -716,17 +715,14 @@ client_node_port_use_buffers(void *object,
m = find_mem(data, buffers[i].mem_id);
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;
res = -ENODEV;
goto error_exit_cleanup;
}
bid = pw_array_add(&mix->buffers, sizeof(struct buffer));
if (bid == NULL) {
res = -errno;
pw_proxy_error(proxy, res, "error allocating buffers : %m");
goto cleanup;
goto error_exit_cleanup;
}
bid->id = i;
@ -735,8 +731,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, "use_buffers: can't mmap memory: %m");
goto cleanup;
goto error_exit_cleanup;
}
if (mlock(bmem.map.ptr, bmem.map.map.size) < 0)
pw_log_warn("Failed to mlock memory %u %u: %m",
@ -754,8 +749,7 @@ client_node_port_use_buffers(void *object,
b = bid->buf = malloc(size);
if (b == NULL) {
res = -errno;
pw_proxy_error(proxy, res, "can't alloc memory: %s", spa_strerror(res));
goto cleanup;
goto error_exit_cleanup;
}
memcpy(b, buffers[i].buffer, sizeof(struct spa_buffer));
@ -795,9 +789,8 @@ 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;
res = -ENODEV;
goto error_exit_cleanup;
}
d->fd = bm->fd;
@ -824,15 +817,16 @@ client_node_port_use_buffers(void *object,
}
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));
goto error_exit_cleanup;
done:
return res;
cleanup:
error_exit_cleanup:
clear_buffers(data, mix);
goto done;
error_exit:
pw_log_error("port %p: use_buffers: %s", mix, spa_strerror(res));
pw_proxy_error(proxy, res, "port_use_buffers error: %s", spa_strerror(res));
return res;
}
static int
@ -854,9 +848,8 @@ client_node_port_set_io(void *object,
mix = ensure_mix(data, direction, port_id, mix_id);
if (mix == NULL) {
res = -EINVAL;
pw_proxy_error(proxy, res, "can't get mixer: %s", spa_strerror(res));
return res;
res = -ENOENT;
goto error_exit;
}
if (memid == SPA_ID_INVALID) {
@ -866,17 +859,14 @@ client_node_port_set_io(void *object,
else {
m = find_mem(data, memid);
if (m == NULL) {
pw_log_warn("unknown memory id %u", memid);
res = -EINVAL;
pw_proxy_error(proxy, res, "unknown memory id %u", memid);
return res;
res = -ENODEV;
goto error_exit;
}
ptr = mem_map(data, &m->map, m->fd,
PROT_READ|PROT_WRITE, offset, size);
if (ptr == NULL) {
res = -errno;
pw_proxy_error(proxy, res, "port_set_io: mmap failed: %m");
return res;
goto error_exit;
}
m->ref++;
@ -901,9 +891,14 @@ client_node_port_set_io(void *object,
id,
ptr,
size)) < 0)
pw_proxy_error(proxy, res, "set_io failed: %s", spa_strerror(res));
goto error_exit;
}
return res;
error_exit:
pw_log_error("port %p: set_io: %s", mix, spa_strerror(res));
pw_proxy_error(proxy, res, "port_set_io failed: %s", spa_strerror(res));
return res;
}
static int link_signal_func(void *user_data)
@ -946,16 +941,14 @@ client_node_set_activation(void *object,
else {
m = find_mem(data, memid);
if (m == NULL) {
pw_log_warn("unknown memory id %u", memid);
res = -EINVAL;
pw_proxy_error(proxy, res, "unknown memory id %u", memid);
return res;
res = -ENODEV;
goto error_exit;
}
ptr = mem_map(data, &m->map, m->fd,
PROT_READ|PROT_WRITE, offset, size);
if (ptr == NULL) {
pw_proxy_error(proxy, -errno, "set_activation: mmap failed: %m");
return -errno;
res = -errno;
goto error_exit;
}
m->ref++;
}
@ -970,8 +963,10 @@ client_node_set_activation(void *object,
if (ptr) {
link = pw_array_add(&data->links, sizeof(struct link));
if (link == NULL)
return -errno;
if (link == NULL) {
res = -errno;
goto error_exit;
}
link->node_id = node_id;
link->mem_id = memid;
link->target.activation = ptr;
@ -988,13 +983,16 @@ client_node_set_activation(void *object,
} else {
link = find_activation(&data->links, node_id);
if (link == NULL) {
res = -EINVAL;
goto exit;
res = -ENOENT;
goto error_exit;
}
clear_link(data, link);
}
return res;
exit:
error_exit:
pw_log_error("node %p: set activation %d: %s", node, node_id, spa_strerror(res));
pw_proxy_error(proxy, res, "set_activation: %s", spa_strerror(res));
return res;
}

View file

@ -170,17 +170,17 @@ process_messages(struct client_data *data)
if (demarshal[msg->opcode].func(resource, msg) < 0)
goto invalid_message;
}
done:
done:
core->current_client = NULL;
return;
invalid_method:
invalid_method:
pw_log_error("protocol-native %p: invalid method %u on resource %u",
client->protocol, msg->opcode, msg->id);
pw_resource_error(resource, -EINVAL, "invalid method %u", msg->opcode);
pw_client_destroy(client);
goto done;
invalid_message:
invalid_message:
pw_log_error("protocol-native %p: invalid message received %u %u",
client->protocol, msg->id, msg->opcode);
pw_resource_error(resource, -EINVAL, "invalid message %u", msg->opcode);
@ -312,9 +312,9 @@ static struct pw_client *client_new(struct server *s, int fd)
return client;
cleanup_client:
cleanup_client:
pw_client_destroy(client);
exit:
exit:
return NULL;
}
@ -364,10 +364,10 @@ static int lock_socket(struct server *s)
}
return 0;
err_fd:
err_fd:
close(s->fd_lock);
s->fd_lock = -1;
err:
err:
*s->lock_addr = 0;
*s->addr.sun_path = 0;
return res;
@ -457,9 +457,9 @@ static int add_socket(struct pw_protocol *protocol, struct server *s)
}
return 0;
error_close:
error_close:
close(fd);
error:
error:
return res;
}

View file

@ -195,7 +195,7 @@ static int refill_buffer(struct pw_protocol_native_connection *conn, struct buff
return 0;
/* ERRORS */
recv_error:
recv_error:
pw_log_error("could not recvmsg on fd %d: %s", conn->fd, strerror(errno));
return -errno;
}
@ -245,7 +245,7 @@ struct pw_protocol_native_connection *pw_protocol_native_connection_new(struct p
return this;
no_mem:
no_mem:
free(impl->out.buffer_data);
free(impl->in.buffer_data);
free(impl);
@ -514,7 +514,7 @@ int pw_protocol_native_connection_flush(struct pw_protocol_native_connection *co
return 0;
/* ERRORS */
send_error:
send_error:
res = -errno;
pw_log_error("could not sendmsg: %s", strerror(errno));
return res;

View file

@ -128,7 +128,7 @@ struct pw_rtkit_bus *pw_rtkit_bus_get_system(void)
return bus;
error:
error:
free(bus);
pw_log_error("Failed to connect to system bus: %s", error.message);
dbus_error_free(&error);
@ -227,7 +227,7 @@ static long long rtkit_get_int_property(struct pw_rtkit_bus *connection, const c
dbus_message_iter_next(&iter);
}
finish:
finish:
if (m)
dbus_message_unref(m);
@ -313,7 +313,7 @@ int pw_rtkit_make_realtime(struct pw_rtkit_bus *connection, pid_t thread, int pr
ret = 0;
finish:
finish:
if (m)
dbus_message_unref(m);
@ -372,7 +372,7 @@ int pw_rtkit_make_high_priority(struct pw_rtkit_bus *connection, pid_t thread, i
ret = 0;
finish:
finish:
if (m)
dbus_message_unref(m);
@ -519,7 +519,7 @@ static int module_init(struct pw_module *module, struct pw_properties *propertie
return 0;
error:
error:
free(impl);
return res;
}

View file

@ -57,6 +57,9 @@ struct device_data {
static void module_destroy(void *_data)
{
struct device_data *data = _data;
spa_hook_remove(&data->module_listener);
pw_device_destroy(data->this);
}
@ -69,23 +72,26 @@ SPA_EXPORT
int pipewire__module_init(struct pw_module *module, const char *args)
{
struct pw_properties *props = NULL;
char **argv;
char **argv = NULL;
int n_tokens;
struct pw_core *core = pw_module_get_core(module);
struct pw_device *device;
struct device_data *data;
int res;
if (args == NULL)
goto wrong_arguments;
goto error_arguments;
argv = pw_split_strv(args, " \t", 3, &n_tokens);
if (n_tokens < 2)
goto not_enough_arguments;
goto error_arguments;
if (n_tokens == 3) {
props = pw_properties_new_string(argv[2]);
if (props == NULL)
return -ENOMEM;
if (props == NULL) {
res = -errno;
goto error_exit_cleanup;
}
}
device = pw_spa_device_load(core,
@ -95,12 +101,13 @@ int pipewire__module_init(struct pw_module *module, const char *args)
0,
props,
sizeof(struct device_data));
if (device == NULL) {
res = -errno;
goto error_exit_cleanup;
}
pw_free_strv(argv);
if (device == NULL)
return -ENOMEM;
data = pw_spa_device_get_user_data(device);
data->this = device;
data->core = core;
@ -112,9 +119,12 @@ int pipewire__module_init(struct pw_module *module, const char *args)
return 0;
not_enough_arguments:
pw_free_strv(argv);
wrong_arguments:
error_arguments:
res = -EINVAL;
pw_log_error("usage: module-spa-device " MODULE_USAGE);
return -EINVAL;
goto error_exit_cleanup;
error_exit_cleanup:
if (argv)
pw_free_strv(argv);
return res;
}

View file

@ -72,22 +72,24 @@ int pipewire__module_init(struct pw_module *module, const char *args)
{
struct pw_core *core = pw_module_get_core(module);
struct pw_properties *props = NULL;
char **argv;
int n_tokens;
char **argv = NULL;
int n_tokens, res;
struct pw_spa_monitor *monitor;
struct data *data;
if (args == NULL)
goto wrong_arguments;
goto error_arguments;
argv = pw_split_strv(args, " \t", INT_MAX, &n_tokens);
if (n_tokens < 2)
goto not_enough_arguments;
goto error_arguments;
if (n_tokens == 3) {
props = pw_properties_new_string(argv[2]);
if (props == NULL)
return -ENOMEM;
if (props == NULL) {
res = -errno;
goto error_exit_cleanup;
}
}
monitor = pw_spa_monitor_load(core,
@ -95,23 +97,28 @@ int pipewire__module_init(struct pw_module *module, const char *args)
argv[0], argv[1],
props,
sizeof(struct data));
if (monitor == NULL)
return -ENOMEM;
if (monitor == NULL) {
res = -errno;
goto error_exit_cleanup;
}
pw_free_strv(argv);
data = monitor->user_data;
data->monitor = monitor;
pw_free_strv(argv);
pw_module_add_listener(module, &data->module_listener, &module_events, data);
pw_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
return 0;
not_enough_arguments:
pw_free_strv(argv);
wrong_arguments:
error_arguments:
res = -EINVAL;
pw_log_error("usage: module-spa-monitor " MODULE_USAGE);
return -EINVAL;
goto error_exit_cleanup;
error_exit_cleanup:
if (argv)
pw_free_strv(argv);
return res;
}

View file

@ -83,13 +83,14 @@ static void *create_object(void *_data,
struct pw_node *node;
const char *factory_name, *name;
struct node_data *nd;
int res;
if (properties == NULL)
goto no_properties;
goto error_properties;
factory_name = pw_properties_get(properties, SPA_KEY_FACTORY_NAME);
if (factory_name == NULL)
goto no_properties;
goto error_properties;
name = pw_properties_get(properties, PW_KEY_NODE_NAME);
if (name == NULL)
@ -104,7 +105,7 @@ static void *create_object(void *_data,
properties,
sizeof(struct node_data));
if (node == NULL)
goto no_mem;
goto error_create_node;
nd = pw_spa_node_get_user_data(node);
nd->node = node;
@ -120,17 +121,24 @@ static void *create_object(void *_data,
return node;
no_properties:
error_properties:
res = -EINVAL;
pw_log_error("factory %p: usage: " FACTORY_USAGE, data->this);
if (resource) {
pw_resource_error(resource, -EINVAL, "usage: " FACTORY_USAGE);
}
return NULL;
no_mem:
pw_log_error("can't create node: no memory");
if (resource) {
pw_resource_error(resource, -ENOMEM, "no memory");
}
if (resource)
pw_resource_error(resource, res, "usage: " FACTORY_USAGE);
goto error_exit_cleanup;
error_create_node:
res = -errno;
pw_log_error("can't create node: %m");
if (resource)
pw_resource_error(resource, res, "can't create node: %s", spa_strerror(res));
goto error_exit;
error_exit_cleanup:
if (properties)
pw_properties_free(properties);
error_exit:
errno = -res;
return NULL;
}

View file

@ -60,6 +60,7 @@ struct node_data {
static void module_destroy(void *_data)
{
struct node_data *data = _data;
spa_hook_remove(&data->module_listener);
pw_node_destroy(data->this);
}
@ -72,23 +73,25 @@ SPA_EXPORT
int pipewire__module_init(struct pw_module *module, const char *args)
{
struct pw_properties *props = NULL;
char **argv;
int n_tokens;
char **argv = NULL;
int n_tokens, res;
struct pw_core *core = pw_module_get_core(module);
struct pw_node *node;
struct node_data *data;
if (args == NULL)
goto wrong_arguments;
goto error_arguments;
argv = pw_split_strv(args, " \t", 3, &n_tokens);
if (n_tokens < 2)
goto not_enough_arguments;
goto error_arguments;
if (n_tokens == 3) {
props = pw_properties_new_string(argv[2]);
if (props == NULL)
return -ENOMEM;
if (props == NULL) {
res = -errno;
goto error_exit_cleanup;
}
}
node = pw_spa_node_load(core,
@ -99,10 +102,12 @@ int pipewire__module_init(struct pw_module *module, const char *args)
props,
sizeof(struct node_data));
pw_free_strv(argv);
if (node == NULL) {
res = -errno;
goto error_exit_cleanup;
}
if (node == NULL)
return -ENOMEM;
pw_free_strv(argv);
data = pw_spa_node_get_user_data(node);
data->this = node;
@ -116,9 +121,12 @@ int pipewire__module_init(struct pw_module *module, const char *args)
return 0;
not_enough_arguments:
pw_free_strv(argv);
wrong_arguments:
error_arguments:
res = -EINVAL;
pw_log_error("usage: module-spa-node " MODULE_USAGE);
return -EINVAL;
goto error_exit_cleanup;
error_exit_cleanup:
if (argv)
pw_free_strv(argv);
return res;
}

View file

@ -142,30 +142,34 @@ struct pw_device *pw_spa_device_load(struct pw_core *core,
handle = pw_core_load_spa_handle(core, factory_name,
properties ? &properties->dict : NULL);
if (handle == NULL) {
res = -errno;
pw_log_error("can't load device handle: %m");
goto exit;
}
if (handle == NULL)
goto error_load;
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Device, &iface)) < 0) {
pw_log_error("can't get device interface %d", res);
goto exit_unload;
}
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Device, &iface)) < 0)
goto error_interface;
this = pw_spa_device_new(core, owner, parent, name, flags,
iface, handle, properties, user_data_size);
if (this == NULL) {
res = -errno;
pw_log_error("can't create device: %m");
goto exit_unload;
}
if (this == NULL)
goto error_device;
return this;
exit_unload:
error_load:
res = -errno;
pw_log_error("can't load device handle: %m");
goto error_exit;
error_interface:
pw_log_error("can't get device interface %d", res);
goto error_exit_unload;
error_device:
res = -errno;
pw_log_error("can't create device: %m");
goto error_exit_unload;
error_exit_unload:
pw_unload_spa_handle(handle);
exit:
error_exit:
errno = -res;
return NULL;
}

View file

@ -117,18 +117,18 @@ static struct monitor_object *add_object(struct pw_spa_monitor *this, uint32_t i
if (handle == NULL) {
res = -errno;
pw_log_error("can't make factory instance: %m");
goto error_free_props;
goto error_exit_free_props;
}
if ((res = spa_handle_get_interface(handle, info->type, &iface)) < 0) {
pw_log_error("can't get %d interface: %s", info->type, spa_strerror(res));
goto error_free_handle;
goto error_exit_free_handle;
}
obj = calloc(1, sizeof(struct monitor_object));
if (obj == NULL) {
res = -errno;
goto error_free_handle;
goto error_exit_free_handle;
}
obj->id = id;
obj->name = strdup(name);
@ -149,19 +149,19 @@ static struct monitor_object *add_object(struct pw_spa_monitor *this, uint32_t i
default:
res = -ENOTSUP;
pw_log_error("interface %d not implemented", obj->type);
goto error_free_object;
goto error_exit_free_object;
}
spa_list_append(&impl->item_list, &obj->link);
return obj;
error_free_object:
error_exit_free_object:
free(obj->name);
free(obj);
error_free_handle:
error_exit_free_handle:
pw_unload_spa_handle(handle);
error_free_props:
error_exit_free_props:
pw_properties_free(props);
errno = -res;
return NULL;
@ -279,18 +279,18 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core,
properties ? &properties->dict : NULL);
if (handle == NULL) {
res = -errno;
goto exit;
goto error_exit;
}
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Monitor, &iface)) < 0) {
pw_log_error("can't get MONITOR interface: %s", spa_strerror(res));
goto exit_unload;
goto error_exit_unload;
}
impl = calloc(1, sizeof(struct impl) + user_data_size);
if (impl == NULL) {
res = -errno;
goto exit_unload;
goto error_exit_unload;
}
impl->core = core;
@ -313,12 +313,11 @@ struct pw_spa_monitor *pw_spa_monitor_load(struct pw_core *core,
return this;
exit_unload:
error_exit_unload:
pw_unload_spa_handle(handle);
exit:
error_exit:
errno = -res;
return NULL;
}
void pw_spa_monitor_destroy(struct pw_spa_monitor *monitor)

View file

@ -125,14 +125,17 @@ pw_spa_node_new(struct pw_core *core,
int res;
this = pw_node_new(core, name, properties, sizeof(struct impl) + user_data_size);
if (this == NULL)
return NULL;
if (this == NULL) {
res = -errno;
goto error_exit;
}
impl = this->user_data;
impl->this = this;
impl->owner = owner;
impl->parent = parent;
impl->node = node;
impl->handle = handle;
impl->flags = flags;
if (user_data_size > 0)
@ -140,7 +143,7 @@ pw_spa_node_new(struct pw_core *core,
pw_node_add_listener(this, &impl->node_listener, &node_events, impl);
if ((res = pw_node_set_implementation(this, impl->node)) < 0)
goto clean_node;
goto error_exit_clean_node;
if (flags & PW_SPA_NODE_FLAG_ASYNC) {
impl->init_pending = spa_node_sync(impl->node, res);
@ -149,8 +152,12 @@ pw_spa_node_new(struct pw_core *core,
}
return this;
clean_node:
error_exit_clean_node:
pw_node_destroy(this);
handle = NULL;
error_exit:
if (handle)
pw_unload_spa_handle(handle);
errno = -res;
return NULL;
@ -257,12 +264,12 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
properties ? &properties->dict : NULL);
if (handle == NULL) {
res = -errno;
goto exit;
goto error_exit_cleanup;
}
if ((res = spa_handle_get_interface(handle, SPA_TYPE_INTERFACE_Node, &iface)) < 0) {
pw_log_error("can't get node interface %d", res);
goto exit_unload;
goto error_exit_unload;
}
if (SPA_RESULT_IS_ASYNC(res))
flags |= PW_SPA_NODE_FLAG_ASYNC;
@ -279,18 +286,20 @@ struct pw_node *pw_spa_node_load(struct pw_core *core,
spa_node, handle, properties, user_data_size);
if (this == NULL) {
res = -errno;
goto exit;
goto error_exit;
}
impl = this->user_data;
impl->handle = handle;
impl->factory_name = strdup(factory_name);
return this;
exit_unload:
error_exit_unload:
pw_unload_spa_handle(handle);
exit:
error_exit_cleanup:
if (properties)
pw_properties_free(properties);
error_exit:
errno = -res;
return NULL;
}