mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
stream: don't allow _connect twice
Check if we already are connected and return -EBUSY to avoid crashing. Fixes #3091
This commit is contained in:
parent
fa3ee2e20b
commit
60718c4b4f
2 changed files with 43 additions and 10 deletions
|
|
@ -144,7 +144,6 @@ struct filter {
|
||||||
|
|
||||||
unsigned int disconnecting:1;
|
unsigned int disconnecting:1;
|
||||||
unsigned int disconnect_core:1;
|
unsigned int disconnect_core:1;
|
||||||
unsigned int subscribe:1;
|
|
||||||
unsigned int draining:1;
|
unsigned int draining:1;
|
||||||
unsigned int allow_mlock:1;
|
unsigned int allow_mlock:1;
|
||||||
unsigned int warn_mlock:1;
|
unsigned int warn_mlock:1;
|
||||||
|
|
@ -1497,6 +1496,9 @@ pw_filter_connect(struct pw_filter *filter,
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct spa_dict_item items[1];
|
struct spa_dict_item items[1];
|
||||||
|
|
||||||
|
if (filter->proxy != NULL || filter->state != PW_FILTER_STATE_UNCONNECTED)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
pw_log_debug("%p: connect", filter);
|
pw_log_debug("%p: connect", filter);
|
||||||
impl->flags = flags;
|
impl->flags = flags;
|
||||||
|
|
||||||
|
|
@ -1532,6 +1534,8 @@ pw_filter_connect(struct pw_filter *filter,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl->disconnecting = false;
|
impl->disconnecting = false;
|
||||||
|
impl->draining = false;
|
||||||
|
impl->driving = false;
|
||||||
filter_set_state(filter, PW_FILTER_STATE_CONNECTING, NULL);
|
filter_set_state(filter, PW_FILTER_STATE_CONNECTING, NULL);
|
||||||
|
|
||||||
if (flags & PW_FILTER_FLAG_DRIVER)
|
if (flags & PW_FILTER_FLAG_DRIVER)
|
||||||
|
|
@ -1587,6 +1591,10 @@ int pw_filter_disconnect(struct pw_filter *filter)
|
||||||
struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this);
|
struct filter *impl = SPA_CONTAINER_OF(filter, struct filter, this);
|
||||||
|
|
||||||
pw_log_debug("%p: disconnect", filter);
|
pw_log_debug("%p: disconnect", filter);
|
||||||
|
|
||||||
|
if (impl->disconnecting)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
impl->disconnecting = true;
|
impl->disconnecting = true;
|
||||||
|
|
||||||
if (filter->proxy) {
|
if (filter->proxy) {
|
||||||
|
|
|
||||||
|
|
@ -1332,6 +1332,14 @@ static int node_event_param(void *object, int seq,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void node_event_destroy(void *data)
|
||||||
|
{
|
||||||
|
struct pw_stream *stream = data;
|
||||||
|
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||||
|
spa_hook_remove(&stream->node_listener);
|
||||||
|
impl->node = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void node_event_info(void *data, const struct pw_node_info *info)
|
static void node_event_info(void *data, const struct pw_node_info *info)
|
||||||
{
|
{
|
||||||
struct pw_stream *stream = data;
|
struct pw_stream *stream = data;
|
||||||
|
|
@ -1359,6 +1367,7 @@ static void node_event_info(void *data, const struct pw_node_info *info)
|
||||||
|
|
||||||
static const struct pw_impl_node_events node_events = {
|
static const struct pw_impl_node_events node_events = {
|
||||||
PW_VERSION_IMPL_NODE_EVENTS,
|
PW_VERSION_IMPL_NODE_EVENTS,
|
||||||
|
.destroy = node_event_destroy,
|
||||||
.info_changed = node_event_info,
|
.info_changed = node_event_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1786,8 +1795,7 @@ static const char *get_media_class(struct stream *impl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT int
|
||||||
int
|
|
||||||
pw_stream_connect(struct pw_stream *stream,
|
pw_stream_connect(struct pw_stream *stream,
|
||||||
enum pw_direction direction,
|
enum pw_direction direction,
|
||||||
uint32_t target_id,
|
uint32_t target_id,
|
||||||
|
|
@ -1803,6 +1811,10 @@ pw_stream_connect(struct pw_stream *stream,
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
pw_log_debug("%p: connect target:%d", stream, target_id);
|
pw_log_debug("%p: connect target:%d", stream, target_id);
|
||||||
|
|
||||||
|
if (impl->node != NULL || stream->state != PW_STREAM_STATE_UNCONNECTED)
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
impl->direction =
|
impl->direction =
|
||||||
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
direction == PW_DIRECTION_INPUT ? SPA_DIRECTION_INPUT : SPA_DIRECTION_OUTPUT;
|
||||||
impl->flags = flags;
|
impl->flags = flags;
|
||||||
|
|
@ -1879,6 +1891,11 @@ pw_stream_connect(struct pw_stream *stream,
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
impl->disconnecting = false;
|
impl->disconnecting = false;
|
||||||
|
impl->drained = false;
|
||||||
|
impl->draining = false;
|
||||||
|
impl->driving = false;
|
||||||
|
impl->trigger = false;
|
||||||
|
impl->using_trigger = false;
|
||||||
stream_set_state(stream, PW_STREAM_STATE_CONNECTING, NULL);
|
stream_set_state(stream, PW_STREAM_STATE_CONNECTING, NULL);
|
||||||
|
|
||||||
if ((str = getenv("PIPEWIRE_NODE")) != NULL)
|
if ((str = getenv("PIPEWIRE_NODE")) != NULL)
|
||||||
|
|
@ -2026,7 +2043,7 @@ int pw_stream_disconnect(struct pw_stream *stream)
|
||||||
pw_log_debug("%p: disconnect", stream);
|
pw_log_debug("%p: disconnect", stream);
|
||||||
|
|
||||||
if (impl->disconnecting)
|
if (impl->disconnecting)
|
||||||
return 0;
|
return -EBUSY;
|
||||||
|
|
||||||
impl->disconnecting = true;
|
impl->disconnecting = true;
|
||||||
|
|
||||||
|
|
@ -2038,10 +2055,9 @@ int pw_stream_disconnect(struct pw_stream *stream)
|
||||||
stream->proxy = NULL;
|
stream->proxy = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (impl->node) {
|
if (impl->node)
|
||||||
pw_impl_node_destroy(impl->node);
|
pw_impl_node_destroy(impl->node);
|
||||||
impl->node = NULL;
|
|
||||||
}
|
|
||||||
if (impl->disconnect_core) {
|
if (impl->disconnect_core) {
|
||||||
impl->disconnect_core = false;
|
impl->disconnect_core = false;
|
||||||
spa_hook_remove(&stream->core_listener);
|
spa_hook_remove(&stream->core_listener);
|
||||||
|
|
@ -2172,9 +2188,13 @@ SPA_EXPORT
|
||||||
int pw_stream_set_active(struct pw_stream *stream, bool active)
|
int pw_stream_set_active(struct pw_stream *stream, bool active)
|
||||||
{
|
{
|
||||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||||
|
|
||||||
pw_log_debug("%p: active:%d", stream, active);
|
pw_log_debug("%p: active:%d", stream, active);
|
||||||
if (impl->node)
|
|
||||||
pw_impl_node_set_active(impl->node, active);
|
if (impl->node == NULL)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
pw_impl_node_set_active(impl->node, active);
|
||||||
|
|
||||||
if (!active || impl->drained)
|
if (!active || impl->drained)
|
||||||
impl->drained = impl->draining = false;
|
impl->drained = impl->draining = false;
|
||||||
|
|
@ -2329,9 +2349,14 @@ SPA_EXPORT
|
||||||
int pw_stream_flush(struct pw_stream *stream, bool drain)
|
int pw_stream_flush(struct pw_stream *stream, bool drain)
|
||||||
{
|
{
|
||||||
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
|
||||||
|
|
||||||
|
if (impl->node == NULL)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
pw_loop_invoke(impl->context->data_loop,
|
pw_loop_invoke(impl->context->data_loop,
|
||||||
drain ? do_drain : do_flush, 1, NULL, 0, true, impl);
|
drain ? do_drain : do_flush, 1, NULL, 0, true, impl);
|
||||||
if (!drain && impl->node != NULL)
|
|
||||||
|
if (!drain)
|
||||||
spa_node_send_command(impl->node->node,
|
spa_node_send_command(impl->node->node,
|
||||||
&SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Flush));
|
&SPA_NODE_COMMAND_INIT(SPA_NODE_COMMAND_Flush));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue