mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-24 21:38:05 -04:00
pipewire: handle allocation failures
And make sure we don't leak things in the error paths.
This commit is contained in:
parent
67e8da3390
commit
2ac7c81958
3 changed files with 36 additions and 18 deletions
|
|
@ -85,6 +85,19 @@ static int do_stop(struct spa_loop *loop, bool async, uint32_t seq,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void data_loop_free(struct pw_data_loop *loop)
|
||||||
|
{
|
||||||
|
if (loop->loop && loop->created)
|
||||||
|
pw_loop_destroy(loop->loop);
|
||||||
|
|
||||||
|
spa_hook_list_clean(&loop->listener_list);
|
||||||
|
|
||||||
|
free(loop->affinity);
|
||||||
|
free(loop->class);
|
||||||
|
pw_free_strv(loop->classes);
|
||||||
|
free(loop);
|
||||||
|
}
|
||||||
|
|
||||||
static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict *props)
|
static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict *props)
|
||||||
{
|
{
|
||||||
struct pw_data_loop *this;
|
struct pw_data_loop *this;
|
||||||
|
|
@ -98,6 +111,7 @@ static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_log_debug("%p: new", this);
|
pw_log_debug("%p: new", this);
|
||||||
|
spa_hook_list_init(&this->listener_list);
|
||||||
|
|
||||||
if (loop == NULL) {
|
if (loop == NULL) {
|
||||||
loop = pw_loop_new(props);
|
loop = pw_loop_new(props);
|
||||||
|
|
@ -142,14 +156,17 @@ static struct pw_data_loop *loop_new(struct pw_loop *loop, const struct spa_dict
|
||||||
goto error_free;
|
goto error_free;
|
||||||
}
|
}
|
||||||
this->classes = pw_strv_parse(class, strlen(class), INT_MAX, NULL);
|
this->classes = pw_strv_parse(class, strlen(class), INT_MAX, NULL);
|
||||||
|
if (this->classes == NULL) {
|
||||||
|
res = -ENOMEM;
|
||||||
|
goto error_free;
|
||||||
|
}
|
||||||
if (!this->loop->name[0])
|
if (!this->loop->name[0])
|
||||||
pw_loop_set_name(this->loop, name);
|
pw_loop_set_name(this->loop, name);
|
||||||
spa_hook_list_init(&this->listener_list);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
error_free:
|
error_free:
|
||||||
free(this);
|
data_loop_free(this);
|
||||||
error_cleanup:
|
error_cleanup:
|
||||||
errno = -res;
|
errno = -res;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -165,7 +182,6 @@ struct pw_data_loop *pw_data_loop_new(const struct spa_dict *props)
|
||||||
return loop_new(NULL, props);
|
return loop_new(NULL, props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Destroy a data loop
|
/** Destroy a data loop
|
||||||
* \param loop the data loop to destroy
|
* \param loop the data loop to destroy
|
||||||
*/
|
*/
|
||||||
|
|
@ -178,15 +194,7 @@ void pw_data_loop_destroy(struct pw_data_loop *loop)
|
||||||
|
|
||||||
pw_data_loop_stop(loop);
|
pw_data_loop_stop(loop);
|
||||||
|
|
||||||
if (loop->created)
|
data_loop_free(loop);
|
||||||
pw_loop_destroy(loop->loop);
|
|
||||||
|
|
||||||
spa_hook_list_clean(&loop->listener_list);
|
|
||||||
|
|
||||||
free(loop->affinity);
|
|
||||||
free(loop->class);
|
|
||||||
pw_free_strv(loop->classes);
|
|
||||||
free(loop);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
|
|
|
||||||
|
|
@ -216,12 +216,15 @@ pw_context_load_module(struct pw_context *context,
|
||||||
|
|
||||||
pw_properties_set(this->properties, PW_KEY_MODULE_NAME, name);
|
pw_properties_set(this->properties, PW_KEY_MODULE_NAME, name);
|
||||||
|
|
||||||
|
spa_list_prepend(&context->module_list, &this->link);
|
||||||
|
|
||||||
this->info.name = name ? strdup(name) : NULL;
|
this->info.name = name ? strdup(name) : NULL;
|
||||||
this->info.filename = filename;
|
this->info.filename = spa_steal_ptr(filename);
|
||||||
filename = NULL;
|
|
||||||
this->info.args = args ? strdup(args) : NULL;
|
this->info.args = args ? strdup(args) : NULL;
|
||||||
|
|
||||||
spa_list_prepend(&context->module_list, &this->link);
|
if ((name != NULL && this->info.name == NULL) ||
|
||||||
|
(args != NULL && this->info.args == NULL))
|
||||||
|
goto error_strdup_fail;
|
||||||
|
|
||||||
this->global = pw_global_new(context,
|
this->global = pw_global_new(context,
|
||||||
PW_TYPE_INTERFACE_Module,
|
PW_TYPE_INTERFACE_Module,
|
||||||
|
|
@ -272,6 +275,9 @@ error_no_mem:
|
||||||
res = -errno;
|
res = -errno;
|
||||||
pw_log_error("can't allocate module: %m");
|
pw_log_error("can't allocate module: %m");
|
||||||
goto error_close;
|
goto error_close;
|
||||||
|
error_strdup_fail:
|
||||||
|
res = -errno;
|
||||||
|
goto error_free_module;
|
||||||
error_no_global:
|
error_no_global:
|
||||||
res = -errno;
|
res = -errno;
|
||||||
pw_log_error("\"%s\": failed to create global: %m", this->info.filename);
|
pw_log_error("\"%s\": failed to create global: %m", this->info.filename);
|
||||||
|
|
|
||||||
|
|
@ -1580,11 +1580,11 @@ stream_new(struct pw_context *context, const char *name,
|
||||||
this = &impl->this;
|
this = &impl->this;
|
||||||
pw_log_debug("%p: new \"%s\"", impl, name);
|
pw_log_debug("%p: new \"%s\"", impl, name);
|
||||||
|
|
||||||
if (props == NULL) {
|
if (props == NULL)
|
||||||
props = pw_properties_new(PW_KEY_MEDIA_NAME, name, NULL);
|
props = pw_properties_new(PW_KEY_MEDIA_NAME, name, NULL);
|
||||||
} else if (pw_properties_get(props, PW_KEY_MEDIA_NAME) == NULL) {
|
else if (pw_properties_get(props, PW_KEY_MEDIA_NAME) == NULL)
|
||||||
pw_properties_set(props, PW_KEY_MEDIA_NAME, name);
|
pw_properties_set(props, PW_KEY_MEDIA_NAME, name);
|
||||||
}
|
|
||||||
if (props == NULL) {
|
if (props == NULL) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto error_properties;
|
goto error_properties;
|
||||||
|
|
@ -1610,6 +1610,10 @@ stream_new(struct pw_context *context, const char *name,
|
||||||
pw_context_conf_update_props(context, "stream.properties", props);
|
pw_context_conf_update_props(context, "stream.properties", props);
|
||||||
|
|
||||||
this->name = name ? strdup(name) : NULL;
|
this->name = name ? strdup(name) : NULL;
|
||||||
|
if (name != NULL && this->name == NULL) {
|
||||||
|
res = -errno;
|
||||||
|
goto error_properties;
|
||||||
|
}
|
||||||
this->node_id = SPA_ID_INVALID;
|
this->node_id = SPA_ID_INVALID;
|
||||||
|
|
||||||
spa_ringbuffer_init(&impl->dequeued.ring);
|
spa_ringbuffer_init(&impl->dequeued.ring);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue