fix some segfaults and lockups

This commit is contained in:
Wim Taymans 2017-07-04 10:50:53 +02:00
parent 791137e9e5
commit 7cccede185
6 changed files with 40 additions and 7 deletions

View file

@ -647,6 +647,8 @@ client_node_set_format(void *object,
struct pw_stream *stream = proxy->object;
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
pw_log_debug("stream %p: format changed %d", stream, seq);
if (impl->format)
free(impl->format);
impl->format = format ? spa_format_copy(format) : NULL;
@ -942,6 +944,8 @@ pw_stream_finish_format(struct pw_stream *stream,
{
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
pw_log_debug("stream %p: finish format %d %d", stream, res, impl->pending_seq);
set_params(stream, n_params, params);
if (SPA_RESULT_IS_OK(res)) {

View file

@ -220,7 +220,8 @@ new_node (GstPipeWireDeviceProvider *self, const struct pw_node_info *info)
gst_caps_append (caps, c1);
}
} else {
type = GST_PIPEWIRE_DEVICE_TYPE_UNKNOWN;
gst_caps_unref(caps);
return NULL;
}
props = gst_structure_new_empty ("pipewire-proplist");
@ -323,7 +324,9 @@ list_node_info_cb (struct pw_context *c,
{
InfoData *data = user_data;
if (info) {
*data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (new_node (data->self, info)));
GstDevice *dev = new_node (data->self, info);
if (dev)
*data->devices = g_list_prepend (*data->devices, gst_object_ref_sink (dev));
} else {
data->end = TRUE;
}

View file

@ -648,7 +648,7 @@ gst_pipewire_sink_setcaps (GstBaseSink * bsink, GstCaps * caps)
while (TRUE) {
state = pwsink->stream->state;
if (state == PW_STREAM_STATE_CONFIGURE)
if (state == PW_STREAM_STATE_READY)
break;
if (state == PW_STREAM_STATE_ERROR)

View file

@ -46,6 +46,7 @@ struct node_info {
struct pw_listener port_removed;
struct pw_listener port_unlinked;
struct pw_listener link_state_changed;
struct pw_listener link_destroy;
};
static struct node_info *find_node_info(struct impl *impl, struct pw_node *node)
@ -66,6 +67,7 @@ static void node_info_free(struct node_info *info)
pw_signal_remove(&info->port_added);
pw_signal_remove(&info->port_removed);
pw_signal_remove(&info->port_unlinked);
pw_signal_remove(&info->link_destroy);
pw_signal_remove(&info->link_state_changed);
free(info);
}
@ -124,6 +126,21 @@ on_link_state_changed(struct pw_listener *listener,
}
}
static void
on_link_destroy(struct pw_listener *listener, struct pw_link *link)
{
struct node_info *info = SPA_CONTAINER_OF(listener, struct node_info, link_destroy);
struct impl *impl = info->impl;
pw_log_debug("module %p: link %p destroyed", impl, link);
pw_signal_remove(&info->port_unlinked);
pw_signal_remove(&info->link_state_changed);
pw_signal_remove(&info->link_destroy);
spa_list_init(&info->port_unlinked.link);
spa_list_init(&info->link_state_changed.link);
spa_list_init(&info->link_destroy.link);
}
static void try_link_port(struct pw_node *node, struct pw_port *port, struct node_info *info)
{
struct impl *impl = info->impl;
@ -168,6 +185,7 @@ static void try_link_port(struct pw_node *node, struct pw_port *port, struct nod
pw_signal_add(&link->port_unlinked, &info->port_unlinked, on_link_port_unlinked);
pw_signal_add(&link->state_changed, &info->link_state_changed, on_link_state_changed);
pw_signal_add(&link->destroy_signal, &info->link_destroy, on_link_destroy);
pw_link_activate(link);

View file

@ -1127,9 +1127,11 @@ void pw_link_destroy(struct pw_link *link)
input_remove(link, link->input);
spa_list_remove(&link->input_link);
link->input = NULL;
output_remove(link, link->output);
spa_list_remove(&link->output_link);
link->output = NULL;
pw_work_queue_destroy(impl->work);

View file

@ -540,21 +540,27 @@ void pw_node_destroy(struct pw_node *node)
pw_signal_emit(&node->destroy_signal, node);
if (!impl->async_init) {
pw_loop_invoke(node->data_loop->loop, do_node_remove, 1, 0, NULL, true, node);
spa_list_remove(&node->link);
pw_global_destroy(node->global);
node->global = NULL;
}
spa_list_for_each_safe(resource, tmp, &node->resource_list, link)
pw_resource_destroy(resource);
pw_loop_invoke(node->data_loop->loop, do_node_remove, 1, 0, NULL, true, node);
pw_log_debug("node %p: destroy ports", node);
spa_list_for_each_safe(port, tmpp, &node->input_ports, link)
spa_list_for_each_safe(port, tmpp, &node->input_ports, link) {
pw_signal_emit(&node->port_removed, node, port);
pw_port_destroy(port);
}
spa_list_for_each_safe(port, tmpp, &node->output_ports, link)
spa_list_for_each_safe(port, tmpp, &node->output_ports, link) {
pw_signal_emit(&node->port_removed, node, port);
pw_port_destroy(port);
}
pw_log_debug("node %p: free", node);
pw_signal_emit(&node->free_signal, node);