From 627dfa3da2b755b07a633d8c7b5727d064ceb6d2 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 19 Sep 2018 13:38:39 +0200 Subject: [PATCH] fix some leaks Make pw_get_client_name() return a static string. Unload the dbus interface. Rename the method to make it more obvious that the interface needs to be unloaded. Free module properties Free remote objects and types Free stream params and the array --- src/gst/gstpipewiredeviceprovider.c | 9 +++------ src/gst/gstpipewiresink.c | 2 +- src/gst/gstpipewiresrc.c | 2 +- src/pipewire/core.c | 8 +++++++- src/pipewire/module.c | 2 ++ src/pipewire/pipewire.c | 15 ++++++++------- src/pipewire/pipewire.h | 6 ++++-- src/pipewire/remote.c | 3 +++ src/pipewire/stream.c | 3 ++- 9 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/gst/gstpipewiredeviceprovider.c b/src/gst/gstpipewiredeviceprovider.c index 663660e78..5349f049f 100644 --- a/src/gst/gstpipewiredeviceprovider.c +++ b/src/gst/gstpipewiredeviceprovider.c @@ -751,7 +751,7 @@ gst_pipewire_device_provider_set_property (GObject * object, GST_WARNING_OBJECT (self, "Empty PipeWire client name not allowed. " "Resetting to default value"); - self->client_name = pw_get_client_name (); + self->client_name = g_strdup(pw_get_client_name ()); } else self->client_name = g_value_dup_string (value); break; @@ -792,7 +792,6 @@ gst_pipewire_device_provider_class_init (GstPipeWireDeviceProviderClass * klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstDeviceProviderClass *dm_class = GST_DEVICE_PROVIDER_CLASS (klass); - gchar *client_name; gobject_class->set_property = gst_pipewire_device_provider_set_property; gobject_class->get_property = gst_pipewire_device_provider_get_property; @@ -802,14 +801,12 @@ gst_pipewire_device_provider_class_init (GstPipeWireDeviceProviderClass * klass) dm_class->start = gst_pipewire_device_provider_start; dm_class->stop = gst_pipewire_device_provider_stop; - client_name = pw_get_client_name (); g_object_class_install_property (gobject_class, PROP_CLIENT_NAME, g_param_spec_string ("client-name", "Client Name", - "The PipeWire client_name_to_use", client_name, + "The PipeWire client_name_to_use", pw_get_client_name (), G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | GST_PARAM_MUTABLE_READY)); - g_free (client_name); gst_device_provider_class_set_static_metadata (dm_class, "PipeWire Device Provider", "Sink/Source/Audio/Video", @@ -820,5 +817,5 @@ gst_pipewire_device_provider_class_init (GstPipeWireDeviceProviderClass * klass) static void gst_pipewire_device_provider_init (GstPipeWireDeviceProvider * self) { - self->client_name = pw_get_client_name (); + self->client_name = g_strdup(pw_get_client_name ()); } diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c index 5096e42e4..cd2aff85f 100644 --- a/src/gst/gstpipewiresink.c +++ b/src/gst/gstpipewiresink.c @@ -262,7 +262,7 @@ static void gst_pipewire_sink_init (GstPipeWireSink * sink) { sink->pool = gst_pipewire_pool_new (); - sink->client_name = pw_get_client_name(); + sink->client_name = g_strdup(pw_get_client_name()); sink->mode = DEFAULT_PROP_MODE; sink->fd = -1; diff --git a/src/gst/gstpipewiresrc.c b/src/gst/gstpipewiresrc.c index 64b8fd61a..1124a19d4 100644 --- a/src/gst/gstpipewiresrc.c +++ b/src/gst/gstpipewiresrc.c @@ -319,7 +319,7 @@ gst_pipewire_src_init (GstPipeWireSrc * src) g_queue_init (&src->queue); - src->client_name = pw_get_client_name (); + src->client_name = g_strdup(pw_get_client_name ()); src->pool = gst_pipewire_pool_new (); src->loop = pw_loop_new (NULL); diff --git a/src/pipewire/core.c b/src/pipewire/core.c index d4a9e1d34..812c592f9 100644 --- a/src/pipewire/core.c +++ b/src/pipewire/core.c @@ -37,6 +37,7 @@ /** \cond */ struct impl { struct pw_core this; + void *dbus_iface; }; @@ -375,11 +376,13 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro pw_map_init(&this->globals, 128, 32); + impl->dbus_iface = pw_load_spa_dbus_interface(this->main_loop); + this->support[0] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DataLoop, this->data_loop->loop); this->support[1] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_MainLoop, this->main_loop->loop); this->support[2] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_LoopUtils, this->main_loop->utils); this->support[3] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_Log, pw_log_get()); - this->support[4] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DBus, pw_get_spa_dbus(this->main_loop)); + this->support[4] = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_DBus, impl->dbus_iface); this->n_support = 5; pw_data_loop_start(this->data_loop_impl); @@ -449,6 +452,7 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro */ void pw_core_destroy(struct pw_core *core) { + struct impl *impl = SPA_CONTAINER_OF(core, struct impl, this); struct pw_global *global, *t; struct pw_module *module, *tm; struct pw_remote *remote, *tr; @@ -479,6 +483,8 @@ void pw_core_destroy(struct pw_core *core) pw_map_clear(&core->globals); + pw_unload_spa_interface(impl->dbus_iface); + pw_log_debug("core %p: free", core); free(core); } diff --git a/src/pipewire/module.c b/src/pipewire/module.c index 250dd9b4c..a4a0dba25 100644 --- a/src/pipewire/module.c +++ b/src/pipewire/module.c @@ -310,6 +310,8 @@ void pw_module_destroy(struct pw_module *module) if (module->info.args) free((char *) module->info.args); + pw_properties_free(module->properties); + dlclose(impl->hnd); free(impl); } diff --git a/src/pipewire/pipewire.c b/src/pipewire/pipewire.c index ba20e6c1a..a9aae2cd7 100644 --- a/src/pipewire/pipewire.c +++ b/src/pipewire/pipewire.c @@ -377,7 +377,7 @@ int pw_unload_spa_interface(void *iface) return 0; } -void *pw_get_spa_dbus(struct pw_loop *loop) +void *pw_load_spa_dbus_interface(struct pw_loop *loop) { struct spa_support support = SPA_SUPPORT_INIT(SPA_TYPE_INTERFACE_LoopUtils, loop->utils); @@ -511,19 +511,20 @@ const char *pw_get_host_name(void) * * \memberof pw_pipewire */ -char *pw_get_client_name(void) +const char *pw_get_client_name(void) { - char *c; const char *cc; + static char cname[256]; if ((cc = pw_get_application_name())) - return strdup(cc); + return cc; else if ((cc = pw_get_prgname())) - return strdup(cc); + return cc; else { - if (asprintf(&c, "pipewire-pid-%zd", (size_t) getpid()) < 0) + if (snprintf(cname, sizeof(cname), "pipewire-pid-%zd", (size_t) getpid()) < 0) return NULL; - return c; + cname[255] = 0; + return cname; } } diff --git a/src/pipewire/pipewire.h b/src/pipewire/pipewire.h index 944c50839..894c04d18 100644 --- a/src/pipewire/pipewire.h +++ b/src/pipewire/pipewire.h @@ -118,7 +118,7 @@ pw_get_user_name(void); const char * pw_get_host_name(void); -char * +const char * pw_get_client_name(void); void @@ -137,9 +137,11 @@ void *pw_load_spa_interface(const char *lib, const char *factory_name, uint32_t const struct spa_dict *info, uint32_t n_support, struct spa_support support[n_support]); + +void *pw_load_spa_dbus_interface(struct pw_loop *loop); + int pw_unload_spa_interface(void *iface); -void *pw_get_spa_dbus(struct pw_loop *loop); const struct spa_handle_factory * pw_get_support_factory(const char *factory_name); diff --git a/src/pipewire/remote.c b/src/pipewire/remote.c index 3448c1fee..cc01cc861 100644 --- a/src/pipewire/remote.c +++ b/src/pipewire/remote.c @@ -303,6 +303,9 @@ void pw_remote_destroy(struct pw_remote *remote) spa_list_remove(&remote->link); + pw_map_clear(&remote->objects); + pw_map_clear(&remote->types); + if (remote->properties) pw_properties_free(remote->properties); free(remote->error); diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index c045c69f4..73c915575 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -151,7 +151,7 @@ static void clear_params(struct pw_stream *stream, int type) p = pw_array_first(&impl->params); while (pw_array_check(&impl->params, p)) { - if (SPA_FLAG_CHECK(p->type, type)) { + if ((p->type & type) != 0) { free(p->param); pw_array_remove(&impl->params, p); } @@ -948,6 +948,7 @@ void pw_stream_destroy(struct pw_stream *stream) spa_list_remove(&stream->link); clear_params(stream, PARAM_TYPE_INIT | PARAM_TYPE_OTHER | PARAM_TYPE_FORMAT); + pw_array_clear(&impl->params); if (stream->error) free(stream->error);