mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
jack: add extra object check
Make an invalid object type and mark removed objects as invalid. Make sure we don't reference an invalid object for the various callbacks and methods. See #1265
This commit is contained in:
parent
01c2cb3d45
commit
7ef78b4464
1 changed files with 38 additions and 20 deletions
|
|
@ -107,9 +107,10 @@ struct object {
|
||||||
|
|
||||||
struct client *client;
|
struct client *client;
|
||||||
|
|
||||||
#define INTERFACE_Port 0
|
#define INTERFACE_Invalid 0
|
||||||
#define INTERFACE_Node 1
|
#define INTERFACE_Port 1
|
||||||
#define INTERFACE_Link 2
|
#define INTERFACE_Node 2
|
||||||
|
#define INTERFACE_Link 3
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
|
|
@ -413,12 +414,23 @@ static struct object * alloc_object(struct client *c, int type)
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_object(struct client *c, struct object *o)
|
static void unlink_object(struct client *c, struct object *o)
|
||||||
{
|
{
|
||||||
pthread_mutex_lock(&c->context.lock);
|
pthread_mutex_lock(&c->context.lock);
|
||||||
spa_list_remove(&o->link);
|
spa_list_remove(&o->link);
|
||||||
pthread_mutex_unlock(&c->context.lock);
|
pthread_mutex_unlock(&c->context.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void recycle_object(struct client *c, struct object *o)
|
||||||
|
{
|
||||||
spa_list_append(&c->context.free_objects, &o->link);
|
spa_list_append(&c->context.free_objects, &o->link);
|
||||||
|
o->type = INTERFACE_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_object(struct client *c, struct object *o)
|
||||||
|
{
|
||||||
|
unlink_object(c, o);
|
||||||
|
recycle_object(c, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init_mix(struct mix *mix, uint32_t mix_id, struct port *port)
|
static void init_mix(struct mix *mix, uint32_t mix_id, struct port *port)
|
||||||
|
|
@ -603,9 +615,18 @@ 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)
|
|
||||||
|
static struct object *find_id(struct client *c, uint32_t id)
|
||||||
{
|
{
|
||||||
struct object *o = pw_map_lookup(&c->context.globals, id);
|
struct object *o = pw_map_lookup(&c->context.globals, id);
|
||||||
|
if (o != NULL && o->type == INTERFACE_Invalid)
|
||||||
|
return NULL;
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct object *find_type(struct client *c, uint32_t id, uint32_t type)
|
||||||
|
{
|
||||||
|
struct object *o = find_id(c, id);
|
||||||
if (o != NULL && o->type == type)
|
if (o != NULL && o->type == type)
|
||||||
return o;
|
return o;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -2304,8 +2325,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 {
|
||||||
o = pw_map_lookup(&c->context.globals, id);
|
if ((o = find_id(c, id)) == NULL)
|
||||||
if (o == NULL)
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
switch (o->type) {
|
switch (o->type) {
|
||||||
|
|
@ -2679,18 +2699,9 @@ 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);
|
||||||
|
|
||||||
o = pw_map_lookup(&c->context.globals, id);
|
if ((o = find_id(c, id)) == 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
|
|
||||||
* they are unregistered. We keep the memory around for that
|
|
||||||
* reason but reuse it when we can. */
|
|
||||||
spa_list_append(&c->context.free_objects, &o->link);
|
|
||||||
if (o->proxy) {
|
if (o->proxy) {
|
||||||
pw_proxy_destroy(o->proxy);
|
pw_proxy_destroy(o->proxy);
|
||||||
o->proxy = NULL;
|
o->proxy = NULL;
|
||||||
|
|
@ -2705,19 +2716,21 @@ static void registry_event_global_remove(void *object, uint32_t id)
|
||||||
c->metadata->default_audio_source[0] = '\0';
|
c->metadata->default_audio_source[0] = '\0';
|
||||||
}
|
}
|
||||||
if (find_node(c, o->node.name) == NULL) {
|
if (find_node(c, o->node.name) == NULL) {
|
||||||
pw_log_info(NAME" %p: client removed \"%s\"", c, o->node.name);
|
pw_log_info(NAME" %p: client %u removed \"%s\"", c, o->id, o->node.name);
|
||||||
do_callback(c, registration_callback,
|
do_callback(c, registration_callback,
|
||||||
o->node.name, 0, c->registration_arg);
|
o->node.name, 0, c->registration_arg);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INTERFACE_Port:
|
case INTERFACE_Port:
|
||||||
pw_log_info(NAME" %p: port removed \"%s\"", c, o->port.name);
|
pw_log_info(NAME" %p: port %u removed \"%s\"", c, o->id, o->port.name);
|
||||||
do_callback(c, portregistration_callback,
|
do_callback(c, portregistration_callback,
|
||||||
o->id, 0, c->portregistration_arg);
|
o->id, 0, c->portregistration_arg);
|
||||||
break;
|
break;
|
||||||
case INTERFACE_Link:
|
case INTERFACE_Link:
|
||||||
if (find_type(c, o->port_link.src, INTERFACE_Port) != NULL &&
|
if (find_type(c, o->port_link.src, INTERFACE_Port) != NULL &&
|
||||||
find_type(c, o->port_link.dst, INTERFACE_Port) != NULL) {
|
find_type(c, o->port_link.dst, INTERFACE_Port) != NULL) {
|
||||||
|
pw_log_info(NAME" %p: link %u %d -> %d removed", c, o->id,
|
||||||
|
o->port_link.src, o->port_link.dst);
|
||||||
do_callback(c, connect_callback,
|
do_callback(c, connect_callback,
|
||||||
o->port_link.src, o->port_link.dst, 0, c->connect_arg);
|
o->port_link.src, o->port_link.dst, 0, c->connect_arg);
|
||||||
} else
|
} else
|
||||||
|
|
@ -2726,6 +2739,11 @@ static void registry_event_global_remove(void *object, uint32_t id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* JACK clients expect the objects to hang around after
|
||||||
|
* they are unregistered. We keep the memory around for that
|
||||||
|
* reason but reuse it when we can. */
|
||||||
|
unlink_object(c, o);
|
||||||
|
recycle_object(c, o);
|
||||||
/* we keep the object available with the id because jack clients
|
/* we keep the object available with the id because jack clients
|
||||||
* tend to access the objects with it later.
|
* tend to access the objects with it later.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue