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 pw_stream *stream = proxy->object;
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
pw_log_debug("stream %p: format changed %d", stream, seq);
if (impl->format) if (impl->format)
free(impl->format); free(impl->format);
impl->format = format ? spa_format_copy(format) : NULL; 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); 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); set_params(stream, n_params, params);
if (SPA_RESULT_IS_OK(res)) { 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); gst_caps_append (caps, c1);
} }
} else { } else {
type = GST_PIPEWIRE_DEVICE_TYPE_UNKNOWN; gst_caps_unref(caps);
return NULL;
} }
props = gst_structure_new_empty ("pipewire-proplist"); props = gst_structure_new_empty ("pipewire-proplist");
@ -323,7 +324,9 @@ list_node_info_cb (struct pw_context *c,
{ {
InfoData *data = user_data; InfoData *data = user_data;
if (info) { 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 { } else {
data->end = TRUE; data->end = TRUE;
} }

View file

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

View file

@ -46,6 +46,7 @@ struct node_info {
struct pw_listener port_removed; struct pw_listener port_removed;
struct pw_listener port_unlinked; struct pw_listener port_unlinked;
struct pw_listener link_state_changed; 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) 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_added);
pw_signal_remove(&info->port_removed); pw_signal_remove(&info->port_removed);
pw_signal_remove(&info->port_unlinked); pw_signal_remove(&info->port_unlinked);
pw_signal_remove(&info->link_destroy);
pw_signal_remove(&info->link_state_changed); pw_signal_remove(&info->link_state_changed);
free(info); 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) static void try_link_port(struct pw_node *node, struct pw_port *port, struct node_info *info)
{ {
struct impl *impl = info->impl; 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->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->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); pw_link_activate(link);

View file

@ -1127,9 +1127,11 @@ void pw_link_destroy(struct pw_link *link)
input_remove(link, link->input); input_remove(link, link->input);
spa_list_remove(&link->input_link); spa_list_remove(&link->input_link);
link->input = NULL;
output_remove(link, link->output); output_remove(link, link->output);
spa_list_remove(&link->output_link); spa_list_remove(&link->output_link);
link->output = NULL;
pw_work_queue_destroy(impl->work); 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); pw_signal_emit(&node->destroy_signal, node);
if (!impl->async_init) { if (!impl->async_init) {
pw_loop_invoke(node->data_loop->loop, do_node_remove, 1, 0, NULL, true, node);
spa_list_remove(&node->link); spa_list_remove(&node->link);
pw_global_destroy(node->global); pw_global_destroy(node->global);
node->global = NULL;
} }
spa_list_for_each_safe(resource, tmp, &node->resource_list, link) spa_list_for_each_safe(resource, tmp, &node->resource_list, link)
pw_resource_destroy(resource); 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); 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); 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_port_destroy(port);
}
pw_log_debug("node %p: free", node); pw_log_debug("node %p: free", node);
pw_signal_emit(&node->free_signal, node); pw_signal_emit(&node->free_signal, node);