mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	context: support foreign mainloop_api
Detect if the mainloop_api is one of ours and use the loop directly in that case. Otherwise, make a new loop and add the fd to the foreign mainloop_api. Make sure we clean up as well. Fixes #345
This commit is contained in:
		
							parent
							
								
									7782352e8d
								
							
						
					
					
						commit
						55b4042512
					
				
					 3 changed files with 51 additions and 5 deletions
				
			
		| 
						 | 
				
			
			@ -1664,12 +1664,24 @@ pa_operation* pa_context_subscribe(pa_context *c, pa_subscription_mask_t m, pa_c
 | 
			
		|||
	return o;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void io_event_cb(pa_mainloop_api*ea, pa_io_event* e, int fd, pa_io_event_flags_t events, void *userdata)
 | 
			
		||||
{
 | 
			
		||||
	pa_context *c = userdata;
 | 
			
		||||
	if (events & PA_IO_EVENT_INPUT) {
 | 
			
		||||
		pw_log_debug("%p: iterate loop %p", c, c->loop);
 | 
			
		||||
		pw_loop_enter(c->loop);
 | 
			
		||||
		pw_loop_iterate(c->loop, -1);
 | 
			
		||||
		pw_loop_leave(c->loop);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPA_EXPORT
 | 
			
		||||
pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *name, PA_CONST pa_proplist *p)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_context *context;
 | 
			
		||||
	struct pw_loop *loop;
 | 
			
		||||
	struct pw_properties *props;
 | 
			
		||||
	bool fallback_loop = false;
 | 
			
		||||
	pa_context *c;
 | 
			
		||||
 | 
			
		||||
	pa_assert(mainloop);
 | 
			
		||||
| 
						 | 
				
			
			@ -1681,7 +1693,15 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 | 
			
		|||
	if (p)
 | 
			
		||||
		pw_properties_update_proplist(props, p);
 | 
			
		||||
 | 
			
		||||
	if (pa_mainloop_api_is_pipewire(mainloop))
 | 
			
		||||
		loop = mainloop->userdata;
 | 
			
		||||
	else  {
 | 
			
		||||
		loop = pw_loop_new(NULL);
 | 
			
		||||
		fallback_loop = true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("mainloop:%p loop:%p", mainloop, loop);
 | 
			
		||||
 | 
			
		||||
	context = pw_context_new(loop,
 | 
			
		||||
			pw_properties_new(
 | 
			
		||||
				PW_KEY_CONTEXT_PROFILE_MODULES, "default",
 | 
			
		||||
| 
						 | 
				
			
			@ -1692,6 +1712,7 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 | 
			
		|||
 | 
			
		||||
	c = pw_context_get_user_data(context);
 | 
			
		||||
	c->props = props;
 | 
			
		||||
	c->fallback_loop = fallback_loop;
 | 
			
		||||
	c->loop = loop;
 | 
			
		||||
	c->context = context;
 | 
			
		||||
	c->proplist = p ? pa_proplist_copy(p) : pa_proplist_new();
 | 
			
		||||
| 
						 | 
				
			
			@ -1699,14 +1720,20 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 | 
			
		|||
	c->client_index = PA_INVALID_INDEX;
 | 
			
		||||
	c->default_sink = SPA_ID_INVALID;
 | 
			
		||||
	c->default_source = SPA_ID_INVALID;
 | 
			
		||||
 | 
			
		||||
	if (name)
 | 
			
		||||
		pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
 | 
			
		||||
 | 
			
		||||
	c->mainloop = mainloop;
 | 
			
		||||
	c->error = 0;
 | 
			
		||||
	c->state = PA_CONTEXT_UNCONNECTED;
 | 
			
		||||
 | 
			
		||||
	if (c->fallback_loop) {
 | 
			
		||||
		c->io = c->mainloop->io_new(c->mainloop,
 | 
			
		||||
				pw_loop_get_fd(c->loop),
 | 
			
		||||
				PA_IO_EVENT_INPUT,
 | 
			
		||||
				io_event_cb, c);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (name)
 | 
			
		||||
		pa_proplist_sets(c->proplist, PA_PROP_APPLICATION_NAME, name);
 | 
			
		||||
 | 
			
		||||
	spa_list_init(&c->globals);
 | 
			
		||||
 | 
			
		||||
	spa_list_init(&c->streams);
 | 
			
		||||
| 
						 | 
				
			
			@ -1718,6 +1745,7 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char *
 | 
			
		|||
 | 
			
		||||
static void context_free(pa_context *c)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_loop *loop;
 | 
			
		||||
	pw_log_debug("context %p: free", c);
 | 
			
		||||
 | 
			
		||||
	context_unlink(c);
 | 
			
		||||
| 
						 | 
				
			
			@ -1728,7 +1756,14 @@ static void context_free(pa_context *c)
 | 
			
		|||
	if (c->core_info)
 | 
			
		||||
		pw_core_info_free(c->core_info);
 | 
			
		||||
 | 
			
		||||
	if (c->io)
 | 
			
		||||
		c->mainloop->io_free(c->io);
 | 
			
		||||
	loop = c->fallback_loop ? c->loop : NULL;
 | 
			
		||||
 | 
			
		||||
	pw_context_destroy(c->context);
 | 
			
		||||
 | 
			
		||||
	if (loop)
 | 
			
		||||
		pw_loop_destroy(loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPA_EXPORT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -346,6 +346,8 @@ struct pa_context {
 | 
			
		|||
	int refcount;
 | 
			
		||||
	uint32_t client_index;
 | 
			
		||||
 | 
			
		||||
	pa_io_event *io;
 | 
			
		||||
	bool fallback_loop;
 | 
			
		||||
	struct pw_loop *loop;
 | 
			
		||||
	struct pw_context *context;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -504,6 +506,7 @@ struct pa_operation
 | 
			
		|||
	void *state_userdata;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool pa_mainloop_api_is_pipewire(pa_mainloop_api *api);
 | 
			
		||||
 | 
			
		||||
pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, size_t userdata_size);
 | 
			
		||||
void pa_operation_done(pa_operation *o);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -272,6 +272,8 @@ pa_mainloop *pa_mainloop_new(void)
 | 
			
		|||
	loop->api = api;
 | 
			
		||||
	loop->api.userdata = loop->loop;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("%p: %p fd:%d", loop, loop->loop, loop->fd);
 | 
			
		||||
 | 
			
		||||
	return loop;
 | 
			
		||||
 | 
			
		||||
      no_loop:
 | 
			
		||||
| 
						 | 
				
			
			@ -279,9 +281,15 @@ pa_mainloop *pa_mainloop_new(void)
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pa_mainloop_api_is_pipewire(pa_mainloop_api *api)
 | 
			
		||||
{
 | 
			
		||||
	return api && api->io_new == api_io_new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SPA_EXPORT
 | 
			
		||||
void pa_mainloop_free(pa_mainloop* m)
 | 
			
		||||
{
 | 
			
		||||
	pw_log_debug("%p", m);
 | 
			
		||||
	pw_loop_destroy(m->loop);
 | 
			
		||||
	free(m);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue