pulse-server: reorder initialization to make proper cleanup possible

Previously, in case of errors, the struct members were not disposed of
correctly, leading to memory leaks. Reordering the initialization slightly
makes it possible to call `impl_free()`.

See https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/1840#note_2106874
This commit is contained in:
Barnabás Pőcze 2023-09-29 18:19:13 +02:00
parent bcc902a55e
commit 37b2633756

View file

@ -5483,9 +5483,23 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
const char *str; const char *str;
int res = 0; int res = 0;
debug_messages = pw_log_topic_enabled(SPA_LOG_LEVEL_INFO, pulse_conn);
impl = calloc(1, sizeof(*impl) + user_data_size); impl = calloc(1, sizeof(*impl) + user_data_size);
if (impl == NULL) if (impl == NULL)
goto error_exit; goto error_free_props;
impl->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
impl->rate_limit.burst = 1;
spa_hook_list_init(&impl->hooks);
spa_list_init(&impl->servers);
pw_map_init(&impl->samples, 16, 16);
pw_map_init(&impl->modules, 16, 16);
spa_list_init(&impl->cleanup_clients);
spa_list_init(&impl->free_messages);
impl->loop = pw_context_get_main_loop(context);
impl->work_queue = pw_context_get_work_queue(context);
if (props == NULL) if (props == NULL)
props = pw_properties_new(NULL, NULL); props = pw_properties_new(NULL, NULL);
@ -5503,25 +5517,6 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
pw_properties_set(props, "vm.overrides", NULL); pw_properties_set(props, "vm.overrides", NULL);
} }
load_defaults(&impl->defs, props);
debug_messages = pw_log_topic_enabled(SPA_LOG_LEVEL_INFO, pulse_conn);
impl->context = context;
impl->loop = pw_context_get_main_loop(context);
impl->props = props;
impl->work_queue = pw_context_get_work_queue(context);
spa_hook_list_init(&impl->hooks);
spa_list_init(&impl->servers);
impl->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
impl->rate_limit.burst = 1;
pw_map_init(&impl->samples, 16, 16);
pw_map_init(&impl->modules, 16, 16);
spa_list_init(&impl->cleanup_clients);
spa_list_init(&impl->free_messages);
str = pw_properties_get(props, "server.address"); str = pw_properties_get(props, "server.address");
if (str == NULL) { if (str == NULL) {
pw_properties_setf(props, "server.address", pw_properties_setf(props, "server.address",
@ -5544,8 +5539,6 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
pw_log_warn("%p: can't create pid file: %s", pw_log_warn("%p: can't create pid file: %s",
impl, spa_strerror(res)); impl, spa_strerror(res));
} }
pw_context_add_listener(context, &impl->context_listener,
&context_events, impl);
#ifdef HAVE_DBUS #ifdef HAVE_DBUS
str = pw_properties_get(props, "server.dbus-name"); str = pw_properties_get(props, "server.dbus-name");
@ -5554,14 +5547,22 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
if (strlen(str) > 0) if (strlen(str) > 0)
impl->dbus_name = dbus_request_name(context, str); impl->dbus_name = dbus_request_name(context, str);
#endif #endif
load_defaults(&impl->defs, props);
impl->props = spa_steal_ptr(props);
pw_context_add_listener(context, &impl->context_listener,
&context_events, impl);
impl->context = context;
cmd_run(impl); cmd_run(impl);
return (struct pw_protocol_pulse *) impl; return (struct pw_protocol_pulse *) impl;
error_free: error_free:
free(impl); impl_free(impl);
error_exit: error_free_props:
pw_properties_free(props); pw_properties_free(props);
if (res < 0) if (res < 0)