mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-11 13:30:07 -05:00
pipewire: fix leak of dbus interface
Track loaded interfaces. Add a method to release the dbus interface when the core is destroyed. Free SDL resources in video-play example
This commit is contained in:
parent
9e60fd0b57
commit
8d2a9fcf62
5 changed files with 74 additions and 11 deletions
|
|
@ -449,5 +449,9 @@ int main(int argc, char *argv[])
|
|||
pw_core_destroy(data.core);
|
||||
pw_main_loop_destroy(data.loop);
|
||||
|
||||
SDL_DestroyTexture(data.texture);
|
||||
SDL_DestroyRenderer(data.renderer);
|
||||
SDL_DestroyWindow(data.window);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -391,12 +391,14 @@ struct pw_core *pw_core_new(struct pw_loop *main_loop, struct pw_properties *pro
|
|||
spa_graph_init(&this->rt.graph);
|
||||
spa_graph_set_callbacks(&this->rt.graph, &spa_graph_impl_default, NULL);
|
||||
|
||||
this->dbus_iface = pw_get_spa_dbus(this->main_loop);
|
||||
|
||||
this->support[0] = SPA_SUPPORT_INIT(SPA_TYPE__TypeMap, this->type.map);
|
||||
this->support[1] = SPA_SUPPORT_INIT(SPA_TYPE_LOOP__DataLoop, this->data_loop->loop);
|
||||
this->support[2] = SPA_SUPPORT_INIT(SPA_TYPE_LOOP__MainLoop, this->main_loop->loop);
|
||||
this->support[3] = SPA_SUPPORT_INIT(SPA_TYPE__LoopUtils, this->main_loop->utils);
|
||||
this->support[4] = SPA_SUPPORT_INIT(SPA_TYPE__Log, pw_log_get());
|
||||
this->support[5] = SPA_SUPPORT_INIT(SPA_TYPE__DBus, pw_get_spa_dbus(this->main_loop));
|
||||
this->support[5] = SPA_SUPPORT_INIT(SPA_TYPE__DBus, this->dbus_iface);
|
||||
this->n_support = 6;
|
||||
|
||||
pw_log_debug("%p", this->support[5].data);
|
||||
|
|
@ -494,6 +496,8 @@ void pw_core_destroy(struct pw_core *core)
|
|||
|
||||
pw_data_loop_destroy(core->data_loop_impl);
|
||||
|
||||
pw_release_spa_dbus(core->dbus_iface);
|
||||
|
||||
pw_properties_free(core->properties);
|
||||
|
||||
pw_map_clear(&core->globals);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,19 @@ static struct support_info {
|
|||
uint32_t n_support;
|
||||
} support_info;
|
||||
|
||||
struct interface {
|
||||
struct spa_list link;
|
||||
struct spa_handle *handle;
|
||||
uint32_t type;
|
||||
void *iface;
|
||||
};
|
||||
|
||||
struct registry {
|
||||
struct spa_list interfaces;
|
||||
};
|
||||
|
||||
static struct registry global_registry;
|
||||
|
||||
static bool
|
||||
open_support(const char *path,
|
||||
const char *lib,
|
||||
|
|
@ -92,7 +105,7 @@ static const struct spa_handle_factory *get_factory(struct support_info *info, c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
static struct interface *
|
||||
load_interface(struct support_info *info,
|
||||
const char *factory_name,
|
||||
const char *type)
|
||||
|
|
@ -101,7 +114,8 @@ load_interface(struct support_info *info,
|
|||
struct spa_handle *handle;
|
||||
uint32_t type_id;
|
||||
const struct spa_handle_factory *factory;
|
||||
void *iface;
|
||||
struct interface *iface;
|
||||
void *ptr;
|
||||
struct spa_type_map *map = NULL;
|
||||
|
||||
factory = get_factory(info, factory_name);
|
||||
|
|
@ -118,12 +132,22 @@ load_interface(struct support_info *info,
|
|||
map = pw_get_support_interface(SPA_TYPE__TypeMap);
|
||||
type_id = map ? spa_type_map_get_id(map, type) : 0;
|
||||
|
||||
if ((res = spa_handle_get_interface(handle, type_id, &iface)) < 0) {
|
||||
if ((res = spa_handle_get_interface(handle, type_id, &ptr)) < 0) {
|
||||
fprintf(stderr, "can't get %s interface %d\n", type, res);
|
||||
goto interface_failed;
|
||||
}
|
||||
|
||||
if ((iface = calloc(1, sizeof(struct interface))) == NULL)
|
||||
goto alloc_failed;
|
||||
|
||||
iface->handle = handle;
|
||||
iface->type = type_id;
|
||||
iface->iface = ptr;
|
||||
spa_list_append(&global_registry.interfaces, &iface->link);
|
||||
|
||||
return iface;
|
||||
|
||||
alloc_failed:
|
||||
interface_failed:
|
||||
spa_handle_clear(handle);
|
||||
init_failed:
|
||||
|
|
@ -175,6 +199,7 @@ void *pw_get_spa_dbus(struct pw_loop *loop)
|
|||
{
|
||||
struct support_info dbus_support_info;
|
||||
const char *str;
|
||||
struct interface *iface;
|
||||
|
||||
dbus_support_info.n_support = support_info.n_support;
|
||||
memcpy(dbus_support_info.support, support_info.support,
|
||||
|
|
@ -186,11 +211,36 @@ void *pw_get_spa_dbus(struct pw_loop *loop)
|
|||
if ((str = getenv("SPA_PLUGIN_DIR")) == NULL)
|
||||
str = PLUGINDIR;
|
||||
|
||||
if (open_support(str, "support/libspa-dbus", &dbus_support_info))
|
||||
return load_interface(&dbus_support_info, "dbus", SPA_TYPE__DBus);
|
||||
|
||||
if (open_support(str, "support/libspa-dbus", &dbus_support_info)) {
|
||||
iface = load_interface(&dbus_support_info, "dbus", SPA_TYPE__DBus);
|
||||
if (iface != NULL)
|
||||
return iface->iface;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static struct interface *find_interface(void *iface)
|
||||
{
|
||||
struct interface *i;
|
||||
spa_list_for_each(i, &global_registry.interfaces, link) {
|
||||
if (i->iface == iface)
|
||||
return i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int pw_release_spa_dbus(void *dbus)
|
||||
{
|
||||
struct interface *iface;
|
||||
|
||||
if ((iface = find_interface(dbus)) == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
spa_list_remove(&iface->link);
|
||||
spa_handle_clear(iface->handle);
|
||||
free(iface->handle);
|
||||
free(iface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Initialize PipeWire
|
||||
*
|
||||
|
|
@ -207,7 +257,7 @@ void *pw_get_spa_dbus(struct pw_loop *loop)
|
|||
void pw_init(int *argc, char **argv[])
|
||||
{
|
||||
const char *str;
|
||||
void *iface;
|
||||
struct interface *iface;
|
||||
struct support_info *info = &support_info;
|
||||
|
||||
if ((str = getenv("PIPEWIRE_DEBUG")))
|
||||
|
|
@ -219,15 +269,17 @@ void pw_init(int *argc, char **argv[])
|
|||
if (support_info.n_support > 0)
|
||||
return;
|
||||
|
||||
spa_list_init(&global_registry.interfaces);
|
||||
|
||||
if (open_support(str, "support/libspa-support", info)) {
|
||||
iface = load_interface(info, "mapper", SPA_TYPE__TypeMap);
|
||||
if (iface != NULL)
|
||||
info->support[info->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE__TypeMap, iface);
|
||||
info->support[info->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE__TypeMap, iface->iface);
|
||||
|
||||
iface = load_interface(info, "logger", SPA_TYPE__Log);
|
||||
if (iface != NULL) {
|
||||
info->support[info->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE__Log, iface);
|
||||
pw_log_set(iface);
|
||||
info->support[info->n_support++] = SPA_SUPPORT_INIT(SPA_TYPE__Log, iface->iface);
|
||||
pw_log_set(iface->iface);
|
||||
}
|
||||
}
|
||||
pw_log_info("version %s", pw_get_library_version());
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ void *
|
|||
pw_get_support_interface(const char *type);
|
||||
|
||||
void *pw_get_spa_dbus(struct pw_loop *loop);
|
||||
int pw_release_spa_dbus(void *dbus);
|
||||
|
||||
const struct spa_handle_factory *
|
||||
pw_get_support_factory(const char *factory_name);
|
||||
|
|
|
|||
|
|
@ -183,6 +183,8 @@ struct pw_core {
|
|||
struct pw_loop *data_loop; /**< data loop for data passing */
|
||||
struct pw_data_loop *data_loop_impl;
|
||||
|
||||
void *dbus_iface;
|
||||
|
||||
struct spa_support support[16]; /**< support for spa plugins */
|
||||
uint32_t n_support; /**< number of support items */
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue