mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
context: cancel operations when globals are removed
Keep track of all the operations pending for a global and cancel them when the global is removed.
This commit is contained in:
parent
3eb1a09cd2
commit
cb7b25277b
4 changed files with 33 additions and 15 deletions
|
|
@ -37,9 +37,17 @@ int pa_context_set_error(pa_context *c, int error) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void global_free(struct global *g)
|
static void global_free(pa_context *c, struct global *g)
|
||||||
{
|
{
|
||||||
|
pa_operation *o, *t;
|
||||||
|
|
||||||
spa_list_remove(&g->link);
|
spa_list_remove(&g->link);
|
||||||
|
|
||||||
|
spa_list_for_each_safe(o, t, &g->operations, owner_link)
|
||||||
|
pa_operation_cancel(o);
|
||||||
|
|
||||||
|
if (g->proxy)
|
||||||
|
spa_hook_remove(&g->proxy_proxy_listener);
|
||||||
if (g->props)
|
if (g->props)
|
||||||
pw_properties_free(g->props);
|
pw_properties_free(g->props);
|
||||||
if (g->destroy)
|
if (g->destroy)
|
||||||
|
|
@ -60,7 +68,7 @@ static void context_unlink(pa_context *c)
|
||||||
PA_STREAM_FAILED : PA_STREAM_TERMINATED);
|
PA_STREAM_FAILED : PA_STREAM_TERMINATED);
|
||||||
}
|
}
|
||||||
spa_list_consume(g, &c->globals, link)
|
spa_list_consume(g, &c->globals, link)
|
||||||
global_free(g);
|
global_free(c, g);
|
||||||
|
|
||||||
spa_list_consume(o, &c->operations, link)
|
spa_list_consume(o, &c->operations, link)
|
||||||
pa_operation_cancel(o);
|
pa_operation_cancel(o);
|
||||||
|
|
@ -300,10 +308,11 @@ static void registry_event_global(void *data, uint32_t id, uint32_t parent_id,
|
||||||
g->parent_id = parent_id;
|
g->parent_id = parent_id;
|
||||||
g->type = type;
|
g->type = type;
|
||||||
g->props = props ? pw_properties_new_dict(props) : NULL;
|
g->props = props ? pw_properties_new_dict(props) : NULL;
|
||||||
|
spa_list_init(&g->operations);
|
||||||
spa_list_append(&c->globals, &g->link);
|
spa_list_append(&c->globals, &g->link);
|
||||||
|
|
||||||
if (set_mask(c, g) == 0) {
|
if (set_mask(c, g) == 0) {
|
||||||
global_free(g);
|
global_free(c, g);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,7 +332,7 @@ static void registry_event_global_remove(void *object, uint32_t id)
|
||||||
emit_event(c, g, PA_SUBSCRIPTION_EVENT_REMOVE);
|
emit_event(c, g, PA_SUBSCRIPTION_EVENT_REMOVE);
|
||||||
|
|
||||||
pw_log_debug("context %p: free %d %p", c, id, g);
|
pw_log_debug("context %p: free %d %p", c, id, g);
|
||||||
global_free(g);
|
global_free(c, g);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_registry_proxy_events registry_events =
|
static const struct pw_registry_proxy_events registry_events =
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,8 @@ struct global {
|
||||||
pa_subscription_mask_t mask;
|
pa_subscription_mask_t mask;
|
||||||
pa_subscription_event_type_t event;
|
pa_subscription_event_type_t event;
|
||||||
|
|
||||||
pa_operation *operation;
|
struct spa_list operations;
|
||||||
|
|
||||||
void *info;
|
void *info;
|
||||||
pw_destroy_t destroy;
|
pw_destroy_t destroy;
|
||||||
|
|
||||||
|
|
@ -390,6 +391,9 @@ struct pa_operation
|
||||||
pa_context *context;
|
pa_context *context;
|
||||||
pa_stream *stream;
|
pa_stream *stream;
|
||||||
|
|
||||||
|
struct spa_list owner_link;
|
||||||
|
struct global *owner;
|
||||||
|
|
||||||
int seq;
|
int seq;
|
||||||
pa_operation_state_t state;
|
pa_operation_state_t state;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
static void node_event_info(void *object, const struct pw_node_info *info)
|
static void node_event_info(void *object, const struct pw_node_info *info)
|
||||||
{
|
{
|
||||||
struct global *g = object;
|
struct global *g = object;
|
||||||
|
pa_operation *o;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
pw_log_debug("update %d", g->id);
|
pw_log_debug("update %d", g->id);
|
||||||
|
|
@ -50,10 +51,8 @@ static void node_event_info(void *object, const struct pw_node_info *info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g->operation) {
|
spa_list_for_each(o, &g->operations, owner_link)
|
||||||
pa_operation_sync(g->operation);
|
pa_operation_sync(o);
|
||||||
g->operation = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void node_event_param(void *object, int seq,
|
static void node_event_param(void *object, int seq,
|
||||||
|
|
@ -173,6 +172,7 @@ static void device_event_info(void *object, const struct pw_device_info *info)
|
||||||
{
|
{
|
||||||
struct global *g = object;
|
struct global *g = object;
|
||||||
pa_card_info *i = &g->card_info.info;
|
pa_card_info *i = &g->card_info.info;
|
||||||
|
pa_operation *o;
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
|
|
||||||
pw_log_debug("update %d %"PRIu64, g->id, info->change_mask);
|
pw_log_debug("update %d %"PRIu64, g->id, info->change_mask);
|
||||||
|
|
@ -208,10 +208,8 @@ static void device_event_info(void *object, const struct pw_device_info *info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (g->operation) {
|
spa_list_for_each(o, &g->operations, owner_link)
|
||||||
pa_operation_sync(g->operation);
|
pa_operation_sync(o);
|
||||||
g->operation = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_device_proxy_events device_events = {
|
static const struct pw_device_proxy_events device_events = {
|
||||||
|
|
@ -265,6 +263,13 @@ static int ensure_global(pa_context *c, struct global *g, pa_operation *o)
|
||||||
const void *events;
|
const void *events;
|
||||||
pw_destroy_t destroy;
|
pw_destroy_t destroy;
|
||||||
|
|
||||||
|
if (o) {
|
||||||
|
if (o->owner)
|
||||||
|
spa_list_remove(&o->owner_link);
|
||||||
|
o->owner = g;
|
||||||
|
spa_list_append(&g->operations, &o->owner_link);
|
||||||
|
}
|
||||||
|
|
||||||
if (g->proxy != NULL)
|
if (g->proxy != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -303,8 +308,6 @@ static int ensure_global(pa_context *c, struct global *g, pa_operation *o)
|
||||||
|
|
||||||
pw_proxy_add_proxy_listener(g->proxy, &g->proxy_proxy_listener, events, g);
|
pw_proxy_add_proxy_listener(g->proxy, &g->proxy_proxy_listener, events, g);
|
||||||
g->destroy = destroy;
|
g->destroy = destroy;
|
||||||
if (o)
|
|
||||||
g->operation = o;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,8 @@ static void operation_unlink(pa_operation *o) {
|
||||||
}
|
}
|
||||||
if (o->stream)
|
if (o->stream)
|
||||||
pa_stream_unref(o->stream);
|
pa_stream_unref(o->stream);
|
||||||
|
if (o->owner)
|
||||||
|
spa_list_remove(&o->owner_link);
|
||||||
o->stream = NULL;
|
o->stream = NULL;
|
||||||
o->callback = NULL;
|
o->callback = NULL;
|
||||||
o->userdata = NULL;
|
o->userdata = NULL;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue