mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	pulse-server: cleanup servers
This commit is contained in:
		
							parent
							
								
									13dfa9d64b
								
							
						
					
					
						commit
						5b8a52cc78
					
				
					 2 changed files with 40 additions and 25 deletions
				
			
		| 
						 | 
					@ -71,6 +71,7 @@ static void impl_free(struct impl *impl)
 | 
				
			||||||
static void module_destroy(void *data)
 | 
					static void module_destroy(void *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = data;
 | 
						struct impl *impl = data;
 | 
				
			||||||
 | 
						pw_log_debug("module %p: destroy", impl);
 | 
				
			||||||
	impl_free(impl);
 | 
						impl_free(impl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,6 +148,12 @@ struct server {
 | 
				
			||||||
	struct spa_list link;
 | 
						struct spa_list link;
 | 
				
			||||||
	struct impl *impl;
 | 
						struct impl *impl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SERVER_TYPE_INVALID	0
 | 
				
			||||||
 | 
					#define SERVER_TYPE_UNIX	1
 | 
				
			||||||
 | 
					#define SERVER_TYPE_INET	2
 | 
				
			||||||
 | 
						uint32_t type;
 | 
				
			||||||
 | 
						struct sockaddr_un addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        struct spa_source *source;
 | 
					        struct spa_source *source;
 | 
				
			||||||
	struct spa_list clients;
 | 
						struct spa_list clients;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -2674,29 +2680,33 @@ static void server_free(struct server *server)
 | 
				
			||||||
	struct impl *impl = server->impl;
 | 
						struct impl *impl = server->impl;
 | 
				
			||||||
	struct client *c;
 | 
						struct client *c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (server->source)
 | 
						pw_log_debug(NAME" %p: free server %p", impl, server);
 | 
				
			||||||
		pw_loop_destroy_source(impl->loop, server->source);
 | 
					
 | 
				
			||||||
 | 
						spa_list_remove(&server->link);
 | 
				
			||||||
	spa_list_consume(c, &server->clients, link)
 | 
						spa_list_consume(c, &server->clients, link)
 | 
				
			||||||
		client_free(c);
 | 
							client_free(c);
 | 
				
			||||||
 | 
						if (server->source)
 | 
				
			||||||
 | 
							pw_loop_destroy_source(impl->loop, server->source);
 | 
				
			||||||
 | 
						if (server->type == SERVER_TYPE_UNIX)
 | 
				
			||||||
 | 
							unlink(server->addr.sun_path);
 | 
				
			||||||
	free(server);
 | 
						free(server);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int make_local_socket(struct impl *impl, const char *name)
 | 
					static int make_local_socket(struct server *server, const char *name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *runtime_dir;
 | 
						const char *runtime_dir;
 | 
				
			||||||
	struct sockaddr_un addr;
 | 
					 | 
				
			||||||
	socklen_t size;
 | 
						socklen_t size;
 | 
				
			||||||
	int name_size, fd, res;
 | 
						int name_size, fd, res;
 | 
				
			||||||
	struct stat socket_stat;
 | 
						struct stat socket_stat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	runtime_dir = get_runtime_dir();
 | 
						runtime_dir = get_runtime_dir();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	addr.sun_family = AF_LOCAL;
 | 
						server->addr.sun_family = AF_LOCAL;
 | 
				
			||||||
	name_size = snprintf(addr.sun_path, sizeof(addr.sun_path),
 | 
						name_size = snprintf(server->addr.sun_path, sizeof(server->addr.sun_path),
 | 
				
			||||||
                             "%s/pulse/%s", runtime_dir, name) + 1;
 | 
					                             "%s/pulse/%s", runtime_dir, name) + 1;
 | 
				
			||||||
	if (name_size > (int) sizeof(addr.sun_path)) {
 | 
						if (name_size > (int) sizeof(server->addr.sun_path)) {
 | 
				
			||||||
		pw_log_error(NAME" %p: %s/%s too long",
 | 
							pw_log_error(NAME" %p: %s/%s too long",
 | 
				
			||||||
					impl, runtime_dir, name);
 | 
										server, runtime_dir, name);
 | 
				
			||||||
		res = -ENAMETOOLONG;
 | 
							res = -ENAMETOOLONG;
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -2705,29 +2715,31 @@ static int make_local_socket(struct impl *impl, const char *name)
 | 
				
			||||||
		res = -errno;
 | 
							res = -errno;
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (stat(addr.sun_path, &socket_stat) < 0) {
 | 
						if (stat(server->addr.sun_path, &socket_stat) < 0) {
 | 
				
			||||||
		if (errno != ENOENT) {
 | 
							if (errno != ENOENT) {
 | 
				
			||||||
			res = -errno;
 | 
								res = -errno;
 | 
				
			||||||
			pw_log_error("server %p: stat %s failed with error: %m",
 | 
								pw_log_error("server %p: stat %s failed with error: %m",
 | 
				
			||||||
					impl, addr.sun_path);
 | 
										server, server->addr.sun_path);
 | 
				
			||||||
			goto error_close;
 | 
								goto error_close;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (socket_stat.st_mode & S_IWUSR || socket_stat.st_mode & S_IWGRP) {
 | 
						} else if (socket_stat.st_mode & S_IWUSR || socket_stat.st_mode & S_IWGRP) {
 | 
				
			||||||
		unlink(addr.sun_path);
 | 
							unlink(server->addr.sun_path);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size = offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path);
 | 
						size = offsetof(struct sockaddr_un, sun_path) + strlen(server->addr.sun_path);
 | 
				
			||||||
	if (bind(fd, (struct sockaddr *) &addr, size) < 0) {
 | 
						if (bind(fd, (struct sockaddr *) &server->addr, size) < 0) {
 | 
				
			||||||
		res = -errno;
 | 
							res = -errno;
 | 
				
			||||||
		pw_log_error(NAME" %p: bind() failed with error: %m", impl);
 | 
							pw_log_error(NAME" %p: bind() failed with error: %m", server);
 | 
				
			||||||
		goto error_close;
 | 
							goto error_close;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (listen(fd, 128) < 0) {
 | 
						if (listen(fd, 128) < 0) {
 | 
				
			||||||
		res = -errno;
 | 
							res = -errno;
 | 
				
			||||||
		pw_log_error(NAME" %p: listen() failed with error: %m", impl);
 | 
							pw_log_error(NAME" %p: listen() failed with error: %m", server);
 | 
				
			||||||
		goto error_close;
 | 
							goto error_close;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	pw_log_info(NAME" listening on unix:%s", addr.sun_path);
 | 
						pw_log_info(NAME" listening on unix:%s", server->addr.sun_path);
 | 
				
			||||||
 | 
						server->type = SERVER_TYPE_UNIX;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return fd;
 | 
						return fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_close:
 | 
					error_close:
 | 
				
			||||||
| 
						 | 
					@ -2736,7 +2748,7 @@ error:
 | 
				
			||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int make_inet_socket(struct impl *impl, uint32_t address, uint16_t port)
 | 
					static int make_inet_socket(struct server *server, uint32_t address, uint16_t port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sockaddr_in addr;
 | 
						struct sockaddr_in addr;
 | 
				
			||||||
	int res, fd, on;
 | 
						int res, fd, on;
 | 
				
			||||||
| 
						 | 
					@ -2748,7 +2760,7 @@ static int make_inet_socket(struct impl *impl, uint32_t address, uint16_t port)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	on = 1;
 | 
						on = 1;
 | 
				
			||||||
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
 | 
						if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &on, sizeof(on)) < 0)
 | 
				
			||||||
		pw_log_warn(NAME" %p: setsockopt(): %m", impl);
 | 
							pw_log_warn(NAME" %p: setsockopt(): %m", server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_zero(addr);
 | 
						spa_zero(addr);
 | 
				
			||||||
	addr.sin_family = AF_INET;
 | 
						addr.sin_family = AF_INET;
 | 
				
			||||||
| 
						 | 
					@ -2757,14 +2769,15 @@ static int make_inet_socket(struct impl *impl, uint32_t address, uint16_t port)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 | 
						if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
 | 
				
			||||||
		res = -errno;
 | 
							res = -errno;
 | 
				
			||||||
		pw_log_error(NAME" %p: bind() failed with error: %m", impl);
 | 
							pw_log_error(NAME" %p: bind() failed with error: %m", server);
 | 
				
			||||||
		goto error_close;
 | 
							goto error_close;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (listen(fd, 5) < 0) {
 | 
						if (listen(fd, 5) < 0) {
 | 
				
			||||||
		res = -errno;
 | 
							res = -errno;
 | 
				
			||||||
		pw_log_error(NAME" %p: listen() failed with error: %m", impl);
 | 
							pw_log_error(NAME" %p: listen() failed with error: %m", server);
 | 
				
			||||||
		goto error_close;
 | 
							goto error_close;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						server->type = SERVER_TYPE_INET;
 | 
				
			||||||
	pw_log_info(NAME" listening on tcp:%08x:%u", address, port);
 | 
						pw_log_info(NAME" listening on tcp:%08x:%u", address, port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return fd;
 | 
						return fd;
 | 
				
			||||||
| 
						 | 
					@ -2786,8 +2799,9 @@ static struct server *create_local_server(struct impl *impl, const char *name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	server->impl = impl;
 | 
						server->impl = impl;
 | 
				
			||||||
	spa_list_init(&server->clients);
 | 
						spa_list_init(&server->clients);
 | 
				
			||||||
 | 
						spa_list_append(&impl->servers, &server->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fd = make_local_socket(impl, name);
 | 
						fd = make_local_socket(server, name);
 | 
				
			||||||
	if (fd < 0) {
 | 
						if (fd < 0) {
 | 
				
			||||||
		res = fd;
 | 
							res = fd;
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
| 
						 | 
					@ -2799,7 +2813,6 @@ static struct server *create_local_server(struct impl *impl, const char *name)
 | 
				
			||||||
		pw_log_error(NAME" %p: can't create server source: %m", impl);
 | 
							pw_log_error(NAME" %p: can't create server source: %m", impl);
 | 
				
			||||||
		goto error_close;
 | 
							goto error_close;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return server;
 | 
						return server;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
error_close:
 | 
					error_close:
 | 
				
			||||||
| 
						 | 
					@ -2821,8 +2834,9 @@ static struct server *create_inet_server(struct impl *impl, uint32_t address, ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	server->impl = impl;
 | 
						server->impl = impl;
 | 
				
			||||||
	spa_list_init(&server->clients);
 | 
						spa_list_init(&server->clients);
 | 
				
			||||||
 | 
						spa_list_append(&impl->servers, &server->link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fd = make_inet_socket(impl, address, port);
 | 
						fd = make_inet_socket(server, address, port);
 | 
				
			||||||
	if (fd < 0) {
 | 
						if (fd < 0) {
 | 
				
			||||||
		res = fd;
 | 
							res = fd;
 | 
				
			||||||
		goto error;
 | 
							goto error;
 | 
				
			||||||
| 
						 | 
					@ -2848,10 +2862,10 @@ error:
 | 
				
			||||||
static void impl_free(struct impl *impl)
 | 
					static void impl_free(struct impl *impl)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct server *s;
 | 
						struct server *s;
 | 
				
			||||||
	if (impl->props)
 | 
					 | 
				
			||||||
		pw_properties_free(impl->props);
 | 
					 | 
				
			||||||
	spa_list_consume(s, &impl->servers, link)
 | 
						spa_list_consume(s, &impl->servers, link)
 | 
				
			||||||
		server_free(s);
 | 
							server_free(s);
 | 
				
			||||||
 | 
						if (impl->props)
 | 
				
			||||||
 | 
							pw_properties_free(impl->props);
 | 
				
			||||||
	free(impl);
 | 
						free(impl);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue