mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	context: add method to add/remove context listener
This commit is contained in:
		
							parent
							
								
									38860630a5
								
							
						
					
					
						commit
						c5e1515b7a
					
				
					 4 changed files with 62 additions and 24 deletions
				
			
		| 
						 | 
					@ -275,19 +275,11 @@ static const struct pw_context_driver_events context_events = {
 | 
				
			||||||
	.complete = context_do_profile,
 | 
						.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)
 | 
					static void stop_listener(struct impl *impl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (impl->listening) {
 | 
						if (impl->listening) {
 | 
				
			||||||
		pw_loop_invoke(impl->data_loop,
 | 
							pw_context_driver_remove_listener(impl->context,
 | 
				
			||||||
                       do_stop, SPA_ID_INVALID, NULL, 0, true, impl);
 | 
								&impl->context_listener);
 | 
				
			||||||
		impl->listening = false;
 | 
							impl->listening = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -306,16 +298,6 @@ static const struct pw_resource_events resource_events = {
 | 
				
			||||||
	.destroy = resource_destroy,
 | 
						.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
 | 
					static int
 | 
				
			||||||
global_bind(void *object, struct pw_impl_client *client, uint32_t permissions,
 | 
					global_bind(void *object, struct pw_impl_client *client, uint32_t permissions,
 | 
				
			||||||
            uint32_t version, uint32_t id)
 | 
					            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) {
 | 
						if (++impl->busy == 1) {
 | 
				
			||||||
		pw_log_info("%p: starting profiler", impl);
 | 
							pw_log_info("%p: starting profiler", impl);
 | 
				
			||||||
		pw_loop_invoke(impl->data_loop,
 | 
							pw_context_driver_add_listener(impl->context,
 | 
				
			||||||
                       do_start, SPA_ID_INVALID, NULL, 0, false, impl);
 | 
								&impl->context_listener,
 | 
				
			||||||
 | 
								&context_events, impl);
 | 
				
			||||||
		impl->listening = true;
 | 
							impl->listening = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -478,6 +478,53 @@ void pw_context_add_listener(struct pw_context *context,
 | 
				
			||||||
	spa_hook_list_append(&context->listener_list, listener, events, data);
 | 
						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
 | 
					SPA_EXPORT
 | 
				
			||||||
const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support)
 | 
					const struct spa_support *pw_context_get_support(struct pw_context *context, uint32_t *n_support)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -423,6 +423,13 @@ struct pw_context_driver_events {
 | 
				
			||||||
	void (*complete) (void *data, struct pw_impl_node *node);
 | 
						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(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(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__)
 | 
					#define pw_registry_resource_global_remove(r,...) pw_registry_resource(r,global_remove,0,__VA_ARGS__)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1515,7 +1515,7 @@ stream_new(struct pw_context *context, const char *name,
 | 
				
			||||||
	impl->allow_mlock = context->settings.mem_allow_mlock;
 | 
						impl->allow_mlock = context->settings.mem_allow_mlock;
 | 
				
			||||||
	impl->warn_mlock = context->settings.mem_warn_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,
 | 
								&impl->context_listener,
 | 
				
			||||||
			&context_events, impl);
 | 
								&context_events, impl);
 | 
				
			||||||
	return 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(&impl->hooks);
 | 
				
			||||||
	spa_hook_list_clean(&stream->listener_list);
 | 
						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)
 | 
						if (impl->data.context)
 | 
				
			||||||
		pw_context_destroy(impl->data.context);
 | 
							pw_context_destroy(impl->data.context);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue