mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
jack: don't emit connect callback with unknown ports
Lookup of globals needs a thread lock or context lock. There is no need to take the context lock when we already have the thread lock. Make a new method to find an object of a type. Check that link objects are referencing valid ports. Check that the connect callback is referencing valid ports. Only return connections with valid ports. See #1265
This commit is contained in:
parent
b98b9e0e77
commit
8c77713a7b
1 changed files with 30 additions and 21 deletions
|
|
@ -603,6 +603,13 @@ static struct object *find_port(struct client *c, const char *name)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
static struct object *find_type(struct client *c, uint32_t id, uint32_t type)
|
||||||
|
{
|
||||||
|
struct object *o = pw_map_lookup(&c->context.globals, id);
|
||||||
|
if (o != NULL && o->type == type)
|
||||||
|
return o;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct object *find_link(struct client *c, uint32_t src, uint32_t dst)
|
static struct object *find_link(struct client *c, uint32_t src, uint32_t dst)
|
||||||
{
|
{
|
||||||
|
|
@ -2297,9 +2304,7 @@ static int metadata_property(void *object, uint32_t id,
|
||||||
c->metadata->default_audio_source[0] = '\0';
|
c->metadata->default_audio_source[0] = '\0';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pthread_mutex_lock(&c->context.lock);
|
|
||||||
o = pw_map_lookup(&c->context.globals, id);
|
o = pw_map_lookup(&c->context.globals, id);
|
||||||
pthread_mutex_unlock(&c->context.lock);
|
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|
@ -2518,10 +2523,9 @@ static void registry_event_global(void *data, uint32_t id,
|
||||||
|
|
||||||
pthread_mutex_lock(&c->context.lock);
|
pthread_mutex_lock(&c->context.lock);
|
||||||
spa_list_append(&c->context.ports, &o->link);
|
spa_list_append(&c->context.ports, &o->link);
|
||||||
ot = pw_map_lookup(&c->context.globals, node_id);
|
|
||||||
pthread_mutex_unlock(&c->context.lock);
|
pthread_mutex_unlock(&c->context.lock);
|
||||||
|
|
||||||
if (ot == NULL || ot->type != INTERFACE_Node)
|
if ((ot = find_type(c, node_id, INTERFACE_Node)) == NULL)
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
|
|
||||||
if (is_monitor && !c->merge_monitor)
|
if (is_monitor && !c->merge_monitor)
|
||||||
|
|
@ -2592,10 +2596,16 @@ static void registry_event_global(void *data, uint32_t id,
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
o->port_link.src = pw_properties_parse_int(str);
|
o->port_link.src = pw_properties_parse_int(str);
|
||||||
|
|
||||||
|
if (find_type(c, o->port_link.src, INTERFACE_Port) == NULL)
|
||||||
|
goto exit_free;
|
||||||
|
|
||||||
if ((str = spa_dict_lookup(props, PW_KEY_LINK_INPUT_PORT)) == NULL)
|
if ((str = spa_dict_lookup(props, PW_KEY_LINK_INPUT_PORT)) == NULL)
|
||||||
goto exit_free;
|
goto exit_free;
|
||||||
o->port_link.dst = pw_properties_parse_int(str);
|
o->port_link.dst = pw_properties_parse_int(str);
|
||||||
|
|
||||||
|
if (find_type(c, o->port_link.dst, INTERFACE_Port) == NULL)
|
||||||
|
goto exit_free;
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: add link %d %d->%d", c, id,
|
pw_log_debug(NAME" %p: add link %d %d->%d", c, id,
|
||||||
o->port_link.src, o->port_link.dst);
|
o->port_link.src, o->port_link.dst);
|
||||||
}
|
}
|
||||||
|
|
@ -2669,14 +2679,14 @@ static void registry_event_global_remove(void *object, uint32_t id)
|
||||||
|
|
||||||
pw_log_debug(NAME" %p: removed: %u", c, id);
|
pw_log_debug(NAME" %p: removed: %u", c, id);
|
||||||
|
|
||||||
pthread_mutex_lock(&c->context.lock);
|
|
||||||
o = pw_map_lookup(&c->context.globals, id);
|
o = pw_map_lookup(&c->context.globals, id);
|
||||||
if (o != NULL)
|
|
||||||
spa_list_remove(&o->link);
|
|
||||||
pthread_mutex_unlock(&c->context.lock);
|
|
||||||
if (o == NULL)
|
if (o == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&c->context.lock);
|
||||||
|
spa_list_remove(&o->link);
|
||||||
|
pthread_mutex_unlock(&c->context.lock);
|
||||||
|
|
||||||
/* JACK clients expect the objects to hang around after
|
/* JACK clients expect the objects to hang around after
|
||||||
* they are unregistered. We keep the memory around for that
|
* they are unregistered. We keep the memory around for that
|
||||||
* reason but reuse it when we can. */
|
* reason but reuse it when we can. */
|
||||||
|
|
@ -2706,8 +2716,13 @@ static void registry_event_global_remove(void *object, uint32_t id)
|
||||||
o->id, 0, c->portregistration_arg);
|
o->id, 0, c->portregistration_arg);
|
||||||
break;
|
break;
|
||||||
case INTERFACE_Link:
|
case INTERFACE_Link:
|
||||||
do_callback(c, connect_callback,
|
if (find_type(c, o->port_link.src, INTERFACE_Port) != NULL &&
|
||||||
o->port_link.src, o->port_link.dst, 0, c->connect_arg);
|
find_type(c, o->port_link.dst, INTERFACE_Port) != NULL) {
|
||||||
|
do_callback(c, connect_callback,
|
||||||
|
o->port_link.src, o->port_link.dst, 0, c->connect_arg);
|
||||||
|
} else
|
||||||
|
pw_log_warn("unlink between unknown ports %d and %d",
|
||||||
|
o->port_link.src, o->port_link.dst);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4073,9 +4088,9 @@ const char ** jack_port_get_all_connections (const jack_client_t *client,
|
||||||
pthread_mutex_lock(&c->context.lock);
|
pthread_mutex_lock(&c->context.lock);
|
||||||
spa_list_for_each(l, &c->context.links, link) {
|
spa_list_for_each(l, &c->context.links, link) {
|
||||||
if (l->port_link.src == o->id)
|
if (l->port_link.src == o->id)
|
||||||
p = pw_map_lookup(&c->context.globals, l->port_link.dst);
|
p = find_type(c, l->port_link.dst, INTERFACE_Port);
|
||||||
else if (l->port_link.dst == o->id)
|
else if (l->port_link.dst == o->id)
|
||||||
p = pw_map_lookup(&c->context.globals, l->port_link.src);
|
p = find_type(c, l->port_link.src, INTERFACE_Port);
|
||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -4869,21 +4884,15 @@ jack_port_t * jack_port_by_id (jack_client_t *client,
|
||||||
jack_port_id_t port_id)
|
jack_port_id_t port_id)
|
||||||
{
|
{
|
||||||
struct client *c = (struct client *) client;
|
struct client *c = (struct client *) client;
|
||||||
struct object *res = NULL, *o;
|
struct object *res = NULL;
|
||||||
|
|
||||||
spa_return_val_if_fail(c != NULL, NULL);
|
spa_return_val_if_fail(c != NULL, NULL);
|
||||||
|
|
||||||
pthread_mutex_lock(&c->context.lock);
|
pthread_mutex_lock(&c->context.lock);
|
||||||
|
|
||||||
o = pw_map_lookup(&c->context.globals, port_id);
|
res = find_type(c, port_id, INTERFACE_Port);
|
||||||
pw_log_debug(NAME" %p: port %d -> %p", c, port_id, o);
|
pw_log_debug(NAME" %p: port %d -> %p", c, port_id, res);
|
||||||
|
|
||||||
if (o == NULL || o->type != INTERFACE_Port)
|
|
||||||
goto exit;
|
|
||||||
|
|
||||||
res = o;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
pthread_mutex_unlock(&c->context.lock);
|
pthread_mutex_unlock(&c->context.lock);
|
||||||
|
|
||||||
if (res == NULL)
|
if (res == NULL)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue