LADI
/
spa
1
Fork 0

context: add method to add/remove context listener

This commit is contained in:
Wim Taymans 2023-05-21 15:36:00 +02:00
parent 38860630a5
commit c5e1515b7a
4 changed files with 62 additions and 24 deletions

View File

@ -275,19 +275,11 @@ static const struct pw_context_driver_events context_events = {
.complete = context_do_profile,
};
static int do_stop(struct spa_loop *loop,
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *impl = user_data;
spa_hook_remove(&impl->context_listener);
return 0;
}
static void stop_listener(struct impl *impl)
{
if (impl->listening) {
pw_loop_invoke(impl->data_loop,
do_stop, SPA_ID_INVALID, NULL, 0, true, impl);
pw_context_driver_remove_listener(impl->context,
&impl->context_listener);
impl->listening = false;
}
}
@ -306,16 +298,6 @@ static const struct pw_resource_events resource_events = {
.destroy = resource_destroy,
};
static int
do_start(struct spa_loop *loop,
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct impl *impl = user_data;
spa_hook_list_append(&impl->context->driver_listener_list,
&impl->context_listener,
&context_events, impl);
return 0;
}
static int
global_bind(void *object, struct pw_impl_client *client, uint32_t permissions,
uint32_t version, uint32_t id)
@ -340,8 +322,9 @@ global_bind(void *object, struct pw_impl_client *client, uint32_t permissions,
if (++impl->busy == 1) {
pw_log_info("%p: starting profiler", impl);
pw_loop_invoke(impl->data_loop,
do_start, SPA_ID_INVALID, NULL, 0, false, impl);
pw_context_driver_add_listener(impl->context,
&impl->context_listener,
&context_events, impl);
impl->listening = true;
}
return 0;

View File

@ -478,6 +478,53 @@ void pw_context_add_listener(struct pw_context *context,
spa_hook_list_append(&context->listener_list, listener, events, data);
}
struct listener_data {
struct spa_hook *listener;
const struct pw_context_driver_events *events;
void *data;
};
static int
do_add_listener(struct spa_loop *loop,
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct pw_context *context = user_data;
const struct listener_data *d = data;
spa_hook_list_append(&context->driver_listener_list,
d->listener, d->events, d->data);
return 0;
}
SPA_EXPORT
void pw_context_driver_add_listener(struct pw_context *context,
struct spa_hook *listener,
const struct pw_context_driver_events *events,
void *data)
{
struct listener_data d = {
.listener = listener,
.events = events,
.data = data };
pw_loop_invoke(context->data_loop,
do_add_listener, SPA_ID_INVALID, &d, sizeof(d), false, context);
}
static int do_remove_listener(struct spa_loop *loop,
bool async, uint32_t seq, const void *data, size_t size, void *user_data)
{
struct spa_hook *listener = user_data;
spa_hook_remove(listener);
return 0;
}
SPA_EXPORT
void pw_context_driver_remove_listener(struct pw_context *context,
struct spa_hook *listener)
{
pw_loop_invoke(context->data_loop,
do_remove_listener, SPA_ID_INVALID, NULL, 0, true, listener);
}
SPA_EXPORT
const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support)
{

View File

@ -423,6 +423,13 @@ struct pw_context_driver_events {
void (*complete) (void *data, struct pw_impl_node *node);
};
void pw_context_driver_add_listener(struct pw_context *context,
struct spa_hook *listener,
const struct pw_context_driver_events *events,
void *data);
void pw_context_driver_remove_listener(struct pw_context *context,
struct spa_hook *listener);
#define pw_registry_resource(r,m,v,...) pw_resource_call(r, struct pw_registry_events,m,v,##__VA_ARGS__)
#define pw_registry_resource_global(r,...) pw_registry_resource(r,global,0,__VA_ARGS__)
#define pw_registry_resource_global_remove(r,...) pw_registry_resource(r,global_remove,0,__VA_ARGS__)

View File

@ -1515,7 +1515,7 @@ stream_new(struct pw_context *context, const char *name,
impl->allow_mlock = context->settings.mem_allow_mlock;
impl->warn_mlock = context->settings.mem_warn_mlock;
spa_hook_list_append(&impl->context->driver_listener_list,
pw_context_driver_add_listener(impl->context,
&impl->context_listener,
&context_events, impl);
return impl;
@ -1683,7 +1683,8 @@ void pw_stream_destroy(struct pw_stream *stream)
spa_hook_list_clean(&impl->hooks);
spa_hook_list_clean(&stream->listener_list);
spa_hook_remove(&impl->context_listener);
pw_context_driver_remove_listener(impl->context,
&impl->context_listener);
if (impl->data.context)
pw_context_destroy(impl->data.context);