diff --git a/src/modules/module-metadata/metadata.c b/src/modules/module-metadata/metadata.c index d26b0278c..56a98331b 100644 --- a/src/modules/module-metadata/metadata.c +++ b/src/modules/module-metadata/metadata.c @@ -112,19 +112,31 @@ static const struct pw_resource_events resource_events = { .destroy = global_unbind, }; -static void impl_resource_pong(void *data, int seq) +static void remove_pending(struct resource_data *d) { - struct resource_data *d = data; - - if (d->pong_seq == seq) { + if (d->pong_seq != 0) { pw_impl_client_set_busy(pw_resource_get_client(d->resource), false); d->pong_seq = 0; d->impl->pending--; } } +static void impl_resource_destroy(void *data) +{ + struct resource_data *d = data; + remove_pending(d); +} + +static void impl_resource_pong(void *data, int seq) +{ + struct resource_data *d = data; + if (d->pong_seq == seq) + remove_pending(d); +} + static const struct pw_resource_events impl_resource_events = { PW_VERSION_RESOURCE_EVENTS, + .destroy = impl_resource_destroy, .pong = impl_resource_pong, }; diff --git a/src/pipewire/impl-device.c b/src/pipewire/impl-device.c index 5c4a4296f..2135e2380 100644 --- a/src/pipewire/impl-device.c +++ b/src/pipewire/impl-device.c @@ -202,7 +202,22 @@ void pw_impl_device_destroy(struct pw_impl_device *device) free(device); } -static void device_pong(void *data, int seq) +static void remove_busy_resource(struct resource_data *d) +{ + if (d->end != -1) { + spa_hook_remove(&d->listener); + d->end = -1; + pw_impl_client_set_busy(d->resource->client, false); + } +} + +static void resource_destroy(void *data) +{ + struct resource_data *d = data; + remove_busy_resource(d); +} + +static void resource_pong(void *data, int seq) { struct resource_data *d = data; struct pw_resource *resource = d->resource; @@ -212,7 +227,8 @@ static void device_pong(void *data, int seq) static const struct pw_resource_events resource_events = { PW_VERSION_RESOURCE_EVENTS, - .pong = device_pong, + .destroy = resource_destroy, + .pong = resource_pong, }; static void result_device_params(void *data, int seq, int res, uint32_t type, const void *result) @@ -280,11 +296,8 @@ static void result_device_params_async(void *data, int seq, int res, uint32_t ty pw_log_debug(NAME" %p: async result %d %d (%d/%d)", d->device, res, seq, d->seq, d->end); - if (seq == d->end) { - spa_hook_remove(&d->listener); - d->end = -1; - pw_impl_client_set_busy(d->resource->client, false); - } + if (seq == d->end) + remove_busy_resource(d); if (seq == d->seq) result_device_params(&d->data, seq, res, type, result); @@ -350,11 +363,8 @@ static void result_device_done(void *data, int seq, int res, uint32_t type, cons pw_log_debug(NAME" %p: async result %d %d (%d/%d)", d->device, res, seq, d->seq, d->end); - if (seq == d->end) { - spa_hook_remove(&d->listener); - d->end = -1; - pw_impl_client_set_busy(d->resource->client, false); - } + if (seq == d->end) + remove_busy_resource(d); } static int device_set_param(void *object, uint32_t id, uint32_t flags, diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index 91723b85a..fb415cdb7 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -58,8 +58,9 @@ struct impl { struct resource_data { struct pw_impl_node *node; - struct pw_resource *resource; + struct pw_resource *resource; + struct spa_hook resource_listener; struct spa_hook object_listener; uint32_t subscribe_ids[MAX_PARAMS]; @@ -414,16 +415,22 @@ static int node_subscribe_params(void *object, uint32_t *ids, uint32_t n_ids) return 0; } +static void remove_busy_resource(struct resource_data *d) +{ + if (d->end != -1) { + spa_hook_remove(&d->listener); + d->end = -1; + pw_impl_client_set_busy(d->resource->client, false); + } +} + static void result_node_sync(void *data, int seq, int res, uint32_t type, const void *result) { struct resource_data *d = data; pw_log_debug(NAME" %p: sync result %d %d (%d/%d)", d->node, res, seq, d->seq, d->end); - if (seq == d->end) { - spa_hook_remove(&d->listener); - d->end = -1; - pw_impl_client_set_busy(d->resource->client, false); - } + if (seq == d->end) + remove_busy_resource(d); } static int node_set_param(void *object, uint32_t id, uint32_t flags, @@ -484,6 +491,26 @@ static const struct pw_node_methods node_methods = { .send_command = node_send_command }; +static void resource_destroy(void *data) +{ + struct resource_data *d = data; + remove_busy_resource(d); +} + +static void resource_pong(void *data, int seq) +{ + struct resource_data *d = data; + struct pw_resource *resource = d->resource; + pw_log_debug(NAME" %p: resource %p: got pong %d", d->node, + resource, seq); +} + +static const struct pw_resource_events resource_events = { + PW_VERSION_RESOURCE_EVENTS, + .destroy = resource_destroy, + .pong = resource_pong, +}; + static int global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, uint32_t version, uint32_t id) @@ -502,6 +529,9 @@ global_bind(void *_data, struct pw_impl_client *client, uint32_t permissions, data->resource = resource; data->end = -1; + pw_resource_add_listener(resource, + &data->resource_listener, + &resource_events, data); pw_resource_add_object_listener(resource, &data->object_listener, &node_methods, data);