node: unlink ports before destroy

First unlink the ports, then destroy them. This is a more natural
way of cleaning up.
Make sure we destroy the node after destroying the ports.
Destroy the port after destroying its controls
Destroy resources after destroying the global
This commit is contained in:
Wim Taymans 2018-02-16 12:04:33 +01:00
parent 3db9a44679
commit 5034770eae
6 changed files with 74 additions and 47 deletions

View file

@ -301,9 +301,8 @@ void pw_client_destroy(struct pw_client *client)
spa_hook_remove(&impl->core_listener);
if (client->registered) {
if (client->registered)
spa_list_remove(&client->link);
}
if (client->global) {
spa_hook_remove(&client->global_listener);

View file

@ -1253,17 +1253,8 @@ void pw_link_destroy(struct pw_link *link)
pw_link_deactivate(link);
if (link->registered) {
if (link->registered)
spa_list_remove(&link->link);
}
if (link->global) {
spa_hook_remove(&link->global_listener);
pw_global_destroy(link->global);
}
spa_list_for_each_safe(resource, tmp, &link->resource_list, link)
pw_resource_destroy(resource);
input_remove(link, link->input);
spa_list_remove(&link->input_link);
@ -1275,6 +1266,14 @@ void pw_link_destroy(struct pw_link *link)
spa_hook_list_call(&link->output->listener_list, struct pw_port_events, link_removed, link);
link->output = NULL;
if (link->global) {
spa_hook_remove(&link->global_listener);
pw_global_destroy(link->global);
}
spa_list_for_each_safe(resource, tmp, &link->resource_list, link)
pw_resource_destroy(resource);
pw_log_debug("link %p: free", impl);
spa_hook_list_call(&link->listener_list, struct pw_link_events, free);

View file

@ -300,6 +300,12 @@ void pw_module_destroy(struct pw_module *module)
pw_log_debug("module %p: destroy", module);
spa_hook_list_call(&module->listener_list, struct pw_module_events, destroy);
spa_list_remove(&module->link);
if (module->global) {
spa_hook_remove(&module->global_listener);
pw_global_destroy(module->global);
}
spa_list_for_each_safe(resource, tmp, &module->resource_list, link)
pw_resource_destroy(resource);
@ -310,12 +316,6 @@ void pw_module_destroy(struct pw_module *module)
if (module->info.args)
free((char *) module->info.args);
spa_list_remove(&module->link);
if (module->global) {
spa_hook_remove(&module->global_listener);
pw_global_destroy(module->global);
}
dlclose(impl->hnd);
free(impl);
}

View file

@ -621,25 +621,29 @@ void pw_node_destroy(struct pw_node *node)
spa_list_remove(&node->link);
}
if (node->global) {
spa_hook_remove(&node->global_listener);
pw_global_destroy(node->global);
}
spa_list_for_each_safe(resource, tmp, &node->resource_list, link)
pw_resource_destroy(resource);
pw_log_debug("node %p: unlink ports", node);
spa_list_for_each(port, &node->input_ports, link)
pw_port_unlink(port);
spa_list_for_each(port, &node->output_ports, link)
pw_port_unlink(port);
pw_log_debug("node %p: destroy ports", node);
spa_list_for_each_safe(port, tmpp, &node->input_ports, link) {
spa_hook_list_call(&node->listener_list, struct pw_node_events, port_removed, port);
pw_port_destroy(port);
}
spa_list_for_each_safe(port, tmpp, &node->output_ports, link) {
spa_hook_list_call(&node->listener_list, struct pw_node_events, port_removed, port);
pw_port_destroy(port);
}
if (node->global) {
spa_hook_remove(&node->global_listener);
pw_global_destroy(node->global);
}
spa_list_for_each_safe(resource, tmp, &node->resource_list, link)
pw_resource_destroy(resource);
pw_log_debug("node %p: free", node);
spa_hook_list_call(&node->listener_list, struct pw_node_events, free);

View file

@ -391,6 +391,20 @@ int pw_port_add(struct pw_port *port, struct pw_node *node)
return 0;
}
void pw_port_unlink(struct pw_port *port)
{
struct pw_link *l, *t;
if (port->direction == PW_DIRECTION_OUTPUT) {
spa_list_for_each_safe(l, t, &port->links, output_link)
pw_link_destroy(l);
}
else {
spa_list_for_each_safe(l, t, &port->links, input_link)
pw_link_destroy(l);
}
}
static int do_remove_port(struct spa_loop *loop,
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
@ -409,6 +423,28 @@ static int do_remove_port(struct spa_loop *loop,
return 0;
}
static void pw_port_remove(struct pw_port *port)
{
struct pw_node *node = port->node;
pw_log_debug("port %p: remove", port);
if (port->rt.graph)
pw_loop_invoke(port->node->data_loop, do_remove_port,
SPA_ID_INVALID, NULL, 0, true, port);
if (port->direction == PW_DIRECTION_INPUT) {
pw_map_remove(&node->input_port_map, port->port_id);
node->info.n_input_ports--;
}
else {
pw_map_remove(&node->output_port_map, port->port_id);
node->info.n_output_ports--;
}
spa_list_remove(&port->link);
spa_hook_list_call(&node->listener_list, struct pw_node_events, port_removed, port);
}
void pw_port_destroy(struct pw_port *port)
{
struct pw_node *node = port->node;
@ -418,33 +454,19 @@ void pw_port_destroy(struct pw_port *port)
spa_hook_list_call(&port->listener_list, struct pw_port_events, destroy);
if (port->global) {
spa_hook_remove(&port->global_listener);
pw_global_destroy(port->global);
}
if (node) {
if (port->rt.graph)
pw_loop_invoke(port->node->data_loop, do_remove_port,
SPA_ID_INVALID, NULL, 0, true, port);
if (port->direction == PW_DIRECTION_INPUT) {
pw_map_remove(&node->input_port_map, port->port_id);
node->info.n_input_ports--;
}
else {
pw_map_remove(&node->output_port_map, port->port_id);
node->info.n_output_ports--;
}
spa_list_remove(&port->link);
spa_hook_list_call(&node->listener_list, struct pw_node_events, port_removed, port);
}
if (node)
pw_port_remove(port);
spa_list_for_each_safe(control, ctemp, &port->control_list[0], port_link)
pw_control_destroy(control);
spa_list_for_each_safe(control, ctemp, &port->control_list[1], port_link)
pw_control_destroy(control);
if (port->global) {
spa_hook_remove(&port->global_listener);
pw_global_destroy(port->global);
}
pw_log_debug("port %p: free", port);
spa_hook_list_call(&port->listener_list, struct pw_port_events, free);

View file

@ -487,6 +487,9 @@ void * pw_port_get_user_data(struct pw_port *port);
/** Add a port to a node \memberof pw_port */
int pw_port_add(struct pw_port *port, struct pw_node *node);
/** Unlink a port \memberof pw_port */
void pw_port_unlink(struct pw_port *port);
/** Destroy a port \memberof pw_port */
void pw_port_destroy(struct pw_port *port);