mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Improve debug
Add proxy destroy function and use it to free proxy user_data. Destroy sources from the poll thread. Fix format init
This commit is contained in:
		
							parent
							
								
									cf94117244
								
							
						
					
					
						commit
						f6ca32cdcf
					
				
					 12 changed files with 120 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -25,12 +25,17 @@
 | 
			
		|||
#include <unistd.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
 | 
			
		||||
#include <spa/lib/debug.h>
 | 
			
		||||
 | 
			
		||||
#include "pipewire.h"
 | 
			
		||||
#include "connection.h"
 | 
			
		||||
#include "log.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_BUFFER_SIZE 4096
 | 
			
		||||
#define MAX_FDS 28
 | 
			
		||||
 | 
			
		||||
static bool debug_messages = 0;
 | 
			
		||||
 | 
			
		||||
struct buffer {
 | 
			
		||||
	uint8_t *buffer_data;
 | 
			
		||||
	size_t buffer_size;
 | 
			
		||||
| 
						 | 
				
			
			@ -161,6 +166,8 @@ struct pw_connection *pw_connection_new(int fd)
 | 
			
		|||
	if (impl == NULL)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	debug_messages = pw_debug_is_category_enabled("connection");
 | 
			
		||||
 | 
			
		||||
	this = &impl->this;
 | 
			
		||||
 | 
			
		||||
	pw_log_debug("connection %p: new", this);
 | 
			
		||||
| 
						 | 
				
			
			@ -271,7 +278,11 @@ pw_connection_get_next(struct pw_connection *conn,
 | 
			
		|||
	*dt = buf->data;
 | 
			
		||||
	*sz = buf->size;
 | 
			
		||||
 | 
			
		||||
//  spa_debug_pod (data);
 | 
			
		||||
 | 
			
		||||
	if (debug_messages) {
 | 
			
		||||
		printf("<<<<<<<<< in:\n");
 | 
			
		||||
	        spa_debug_pod((struct spa_pod *)data, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -299,6 +310,11 @@ pw_connection_end_write(struct pw_connection *conn, uint32_t dest_id, uint8_t op
 | 
			
		|||
 | 
			
		||||
	buf->buffer_size += 8 + size;
 | 
			
		||||
 | 
			
		||||
	if (debug_messages) {
 | 
			
		||||
		printf(">>>>>>>>> out:\n");
 | 
			
		||||
	        spa_debug_pod((struct spa_pod *)p, NULL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pw_signal_emit(&conn->need_flush, conn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -254,6 +254,26 @@ static const struct pw_link_events link_events = {
 | 
			
		|||
	&link_event_info
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
destroy_proxy (struct pw_proxy *proxy)
 | 
			
		||||
{
 | 
			
		||||
	if (proxy->user_data == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (proxy->type == proxy->context->type.core) {
 | 
			
		||||
		pw_core_info_free (proxy->user_data);
 | 
			
		||||
	} else if (proxy->type == proxy->context->type.node) {
 | 
			
		||||
		pw_node_info_free (proxy->user_data);
 | 
			
		||||
	} else if (proxy->type == proxy->context->type.module) {
 | 
			
		||||
		pw_module_info_free (proxy->user_data);
 | 
			
		||||
	} else if (proxy->type == proxy->context->type.client) {
 | 
			
		||||
		pw_client_info_free (proxy->user_data);
 | 
			
		||||
	} else if (proxy->type == proxy->context->type.link) {
 | 
			
		||||
		pw_link_info_free (proxy->user_data);
 | 
			
		||||
	}
 | 
			
		||||
	proxy->user_data = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void registry_event_global(void *object, uint32_t id, const char *type)
 | 
			
		||||
{
 | 
			
		||||
	struct pw_proxy *registry_proxy = object;
 | 
			
		||||
| 
						 | 
				
			
			@ -292,6 +312,7 @@ static void registry_event_global(void *object, uint32_t id, const char *type)
 | 
			
		|||
		proxy->implementation = &link_events;
 | 
			
		||||
	}
 | 
			
		||||
	if (proxy) {
 | 
			
		||||
		proxy->destroy = (pw_destroy_t)destroy_proxy;
 | 
			
		||||
		pw_registry_do_bind(registry_proxy, id, proxy->id);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -467,6 +488,7 @@ void pw_context_destroy(struct pw_context *context)
 | 
			
		|||
	    pw_proxy_destroy(proxy);
 | 
			
		||||
 | 
			
		||||
	pw_map_clear(&context->objects);
 | 
			
		||||
	pw_map_clear(&context->types);
 | 
			
		||||
 | 
			
		||||
	free(context->name);
 | 
			
		||||
	if (context->properties)
 | 
			
		||||
| 
						 | 
				
			
			@ -565,6 +587,7 @@ bool pw_context_connect_fd(struct pw_context *context, enum pw_context_flags fla
 | 
			
		|||
		goto no_proxy;
 | 
			
		||||
 | 
			
		||||
	context->core_proxy->implementation = &core_events;
 | 
			
		||||
	context->core_proxy->destroy = (pw_destroy_t)destroy_proxy;
 | 
			
		||||
 | 
			
		||||
	pw_core_do_client_update(context->core_proxy, &context->properties->dict);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -190,9 +190,6 @@ struct pw_core_info *pw_core_info_update(struct pw_core_info *info,
 | 
			
		|||
 | 
			
		||||
void pw_core_info_free(struct pw_core_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (info->user_name)
 | 
			
		||||
		free((void *) info->user_name);
 | 
			
		||||
	if (info->host_name)
 | 
			
		||||
| 
						 | 
				
			
			@ -286,8 +283,6 @@ void pw_node_info_free(struct pw_node_info *info)
 | 
			
		|||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if (info->name)
 | 
			
		||||
		free((void *) info->name);
 | 
			
		||||
	if (info->input_formats) {
 | 
			
		||||
| 
						 | 
				
			
			@ -351,9 +346,6 @@ struct pw_module_info *pw_module_info_update(struct pw_module_info *info,
 | 
			
		|||
 | 
			
		||||
void pw_module_info_free(struct pw_module_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (info->name)
 | 
			
		||||
		free((void *) info->name);
 | 
			
		||||
	if (info->filename)
 | 
			
		||||
| 
						 | 
				
			
			@ -395,8 +387,6 @@ struct pw_client_info *pw_client_info_update(struct pw_client_info *info,
 | 
			
		|||
 | 
			
		||||
void pw_client_info_free(struct pw_client_info *info)
 | 
			
		||||
{
 | 
			
		||||
	if (info == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	if (info->props)
 | 
			
		||||
		pw_spa_dict_destroy(info->props);
 | 
			
		||||
	free(info);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,11 @@ struct debug_log {
 | 
			
		|||
static void
 | 
			
		||||
do_logv(struct spa_log *log,
 | 
			
		||||
	enum spa_log_level level,
 | 
			
		||||
	const char *file, int line, const char *func, const char *fmt, va_list args)
 | 
			
		||||
	const char *file,
 | 
			
		||||
	int line,
 | 
			
		||||
	const char *func,
 | 
			
		||||
	const char *fmt,
 | 
			
		||||
	va_list args)
 | 
			
		||||
{
 | 
			
		||||
	struct debug_log *l = SPA_CONTAINER_OF(log, struct debug_log, log);
 | 
			
		||||
	char text[1024], location[1024];
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +77,11 @@ do_logv(struct spa_log *log,
 | 
			
		|||
 | 
			
		||||
static void
 | 
			
		||||
do_log(struct spa_log *log,
 | 
			
		||||
       enum spa_log_level level, const char *file, int line, const char *func, const char *fmt, ...)
 | 
			
		||||
       enum spa_log_level level,
 | 
			
		||||
       const char *file,
 | 
			
		||||
       int line,
 | 
			
		||||
       const char *func,
 | 
			
		||||
       const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	va_list args;
 | 
			
		||||
	va_start(args, fmt);
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +147,10 @@ void pw_log_set_trace_event(struct spa_source *source)
 | 
			
		|||
 | 
			
		||||
void
 | 
			
		||||
pw_log_log(enum spa_log_level level,
 | 
			
		||||
	   const char *file, int line, const char *func, const char *fmt, ...)
 | 
			
		||||
	   const char *file,
 | 
			
		||||
	   int line,
 | 
			
		||||
	   const char *func,
 | 
			
		||||
	   const char *fmt, ...)
 | 
			
		||||
{
 | 
			
		||||
	if (SPA_UNLIKELY(pw_log_level_enabled(level))) {
 | 
			
		||||
		va_list args;
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +162,11 @@ pw_log_log(enum spa_log_level level,
 | 
			
		|||
 | 
			
		||||
void
 | 
			
		||||
pw_log_logv(enum spa_log_level level,
 | 
			
		||||
	    const char *file, int line, const char *func, const char *fmt, va_list args)
 | 
			
		||||
	    const char *file,
 | 
			
		||||
	    int line,
 | 
			
		||||
	    const char *func,
 | 
			
		||||
	    const char *fmt,
 | 
			
		||||
	    va_list args)
 | 
			
		||||
{
 | 
			
		||||
	if (SPA_UNLIKELY(pw_log_level_enabled(level))) {
 | 
			
		||||
		do_logv(&log.log, level, file, line, func, fmt, args);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,6 +50,7 @@ struct impl {
 | 
			
		|||
	struct pw_loop this;
 | 
			
		||||
 | 
			
		||||
	struct spa_list source_list;
 | 
			
		||||
	struct spa_list destroy_list;
 | 
			
		||||
 | 
			
		||||
	spa_loop_hook_t pre_func;
 | 
			
		||||
	spa_loop_hook_t post_func;
 | 
			
		||||
| 
						 | 
				
			
			@ -276,6 +277,7 @@ static int loop_iterate(struct spa_loop_control *ctrl, int timeout)
 | 
			
		|||
	struct pw_loop *loop = &impl->this;
 | 
			
		||||
	struct epoll_event ep[32];
 | 
			
		||||
	int i, nfds, save_errno;
 | 
			
		||||
	struct source_impl *source, *tmp;
 | 
			
		||||
 | 
			
		||||
	pw_signal_emit(&loop->before_iterate, loop);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -297,15 +299,20 @@ static int loop_iterate(struct spa_loop_control *ctrl, int timeout)
 | 
			
		|||
	 * some callback might also want to look at other sources it manages and
 | 
			
		||||
	 * can then reset the rmask to suppress the callback */
 | 
			
		||||
	for (i = 0; i < nfds; i++) {
 | 
			
		||||
		struct spa_source *source = ep[i].data.ptr;
 | 
			
		||||
		source->rmask = spa_epoll_to_io(ep[i].events);
 | 
			
		||||
		struct spa_source *s = ep[i].data.ptr;
 | 
			
		||||
		s->rmask = spa_epoll_to_io(ep[i].events);
 | 
			
		||||
	}
 | 
			
		||||
	for (i = 0; i < nfds; i++) {
 | 
			
		||||
		struct spa_source *source = ep[i].data.ptr;
 | 
			
		||||
		if (source->rmask) {
 | 
			
		||||
			source->func(source);
 | 
			
		||||
		struct spa_source *s = ep[i].data.ptr;
 | 
			
		||||
		if (s->rmask) {
 | 
			
		||||
			s->func(s);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	spa_list_for_each_safe(source, tmp, &impl->destroy_list, link)
 | 
			
		||||
	    free(source);
 | 
			
		||||
 | 
			
		||||
	spa_list_init(&impl->destroy_list);
 | 
			
		||||
 | 
			
		||||
	return SPA_RESULT_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -555,6 +562,7 @@ static struct spa_source *loop_add_signal(struct spa_loop_utils *utils,
 | 
			
		|||
static void loop_destroy_source(struct spa_source *source)
 | 
			
		||||
{
 | 
			
		||||
	struct source_impl *impl = SPA_CONTAINER_OF(source, struct source_impl, source);
 | 
			
		||||
	struct impl *loop_impl = SPA_CONTAINER_OF(source->loop, struct impl, loop);
 | 
			
		||||
 | 
			
		||||
	spa_list_remove(&impl->link);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -562,7 +570,8 @@ static void loop_destroy_source(struct spa_source *source)
 | 
			
		|||
 | 
			
		||||
	if (source->fd != -1 && impl->close)
 | 
			
		||||
		close(source->fd);
 | 
			
		||||
	free(impl);
 | 
			
		||||
 | 
			
		||||
	spa_list_insert(&loop_impl->destroy_list, &impl->link);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct pw_loop *pw_loop_new(void)
 | 
			
		||||
| 
						 | 
				
			
			@ -581,6 +590,7 @@ struct pw_loop *pw_loop_new(void)
 | 
			
		|||
		goto no_epoll;
 | 
			
		||||
 | 
			
		||||
	spa_list_init(&impl->source_list);
 | 
			
		||||
	spa_list_init(&impl->destroy_list);
 | 
			
		||||
 | 
			
		||||
	pw_signal_init(&this->before_iterate);
 | 
			
		||||
	pw_signal_init(&this->destroy_signal);
 | 
			
		||||
| 
						 | 
				
			
			@ -633,6 +643,8 @@ void pw_loop_destroy(struct pw_loop *loop)
 | 
			
		|||
 | 
			
		||||
	spa_list_for_each_safe(source, tmp, &impl->source_list, link)
 | 
			
		||||
	    loop_destroy_source(&source->source);
 | 
			
		||||
	spa_list_for_each_safe(source, tmp, &impl->destroy_list, link)
 | 
			
		||||
	    free(source);
 | 
			
		||||
 | 
			
		||||
	close(impl->epoll_fd);
 | 
			
		||||
	free(impl);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,12 +18,28 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <sys/prctl.h>
 | 
			
		||||
#include <pwd.h>
 | 
			
		||||
 | 
			
		||||
#include "pipewire/client/pipewire.h"
 | 
			
		||||
 | 
			
		||||
static char **categories = NULL;
 | 
			
		||||
 | 
			
		||||
static void configure_debug(const char *str)
 | 
			
		||||
{
 | 
			
		||||
	char **level;
 | 
			
		||||
	int n_tokens;
 | 
			
		||||
 | 
			
		||||
	level = pw_split_strv(str, ":", INT_MAX, &n_tokens);
 | 
			
		||||
	if (n_tokens > 0)
 | 
			
		||||
		pw_log_set_level(atoi(level[0]));
 | 
			
		||||
 | 
			
		||||
	if (n_tokens > 1)
 | 
			
		||||
		categories = pw_split_strv(level[1], ",", INT_MAX, &n_tokens);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * pw_init:
 | 
			
		||||
 * @argc: pointer to argc
 | 
			
		||||
| 
						 | 
				
			
			@ -37,7 +53,21 @@ void pw_init(int *argc, char **argv[])
 | 
			
		|||
	const char *str;
 | 
			
		||||
 | 
			
		||||
	if ((str = getenv("PIPEWIRE_DEBUG")))
 | 
			
		||||
		pw_log_set_level(atoi(str));
 | 
			
		||||
		configure_debug(str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool pw_debug_is_category_enabled(const char *name)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	if (categories == NULL)
 | 
			
		||||
		return false;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; categories[i]; i++) {
 | 
			
		||||
		if (strcmp (categories[i], name) == 0)
 | 
			
		||||
			return true;
 | 
			
		||||
	}
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *pw_get_application_name(void)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,9 @@ extern "C" {
 | 
			
		|||
void
 | 
			
		||||
pw_init(int *argc, char **argv[]);
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
pw_debug_is_category_enabled(const char *name);
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
pw_get_application_name(void);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -71,5 +71,8 @@ void pw_proxy_destroy(struct pw_proxy *proxy)
 | 
			
		|||
	pw_map_remove(&proxy->context->objects, proxy->id);
 | 
			
		||||
	spa_list_remove(&proxy->link);
 | 
			
		||||
 | 
			
		||||
	if (proxy->destroy)
 | 
			
		||||
		proxy->destroy(proxy);
 | 
			
		||||
 | 
			
		||||
	free(impl);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ extern "C" {
 | 
			
		|||
#include <pipewire/client/connection.h>
 | 
			
		||||
#include <pipewire/client/context.h>
 | 
			
		||||
#include <pipewire/client/type.h>
 | 
			
		||||
#include <pipewire/client/utils.h>
 | 
			
		||||
 | 
			
		||||
struct pw_proxy {
 | 
			
		||||
	struct pw_context *context;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +40,7 @@ struct pw_proxy {
 | 
			
		|||
	const void *implementation;
 | 
			
		||||
 | 
			
		||||
	void *user_data;
 | 
			
		||||
        pw_destroy_t destroy;
 | 
			
		||||
 | 
			
		||||
	PW_SIGNAL(destroy_signal, (struct pw_listener *listener, struct pw_proxy *proxy));
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,8 @@ extern "C" {
 | 
			
		|||
#include <spa/defs.h>
 | 
			
		||||
#include <spa/pod-utils.h>
 | 
			
		||||
 | 
			
		||||
typedef void (*pw_destroy_t) (void *object);
 | 
			
		||||
 | 
			
		||||
const char *
 | 
			
		||||
pw_split_walk(const char *str, const char *delimiter, size_t *len, const char **state);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,8 +32,6 @@ extern "C" {
 | 
			
		|||
#include <pipewire/client/sig.h>
 | 
			
		||||
#include <pipewire/server/core.h>
 | 
			
		||||
 | 
			
		||||
typedef void (*pw_destroy_t) (void *object);
 | 
			
		||||
 | 
			
		||||
struct pw_resource {
 | 
			
		||||
	struct pw_core *core;
 | 
			
		||||
	struct spa_list link;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,7 +29,7 @@ extern "C" {
 | 
			
		|||
#include <spa/format.h>
 | 
			
		||||
#include <spa/pod-builder.h>
 | 
			
		||||
 | 
			
		||||
#define SPA_FORMAT_INIT(size,type,media_type,media_subtype,...)		\
 | 
			
		||||
#define SPA_FORMAT_INIT(size,type,media_type,media_subtype)		\
 | 
			
		||||
	{ { size, SPA_POD_TYPE_OBJECT },				\
 | 
			
		||||
	  { { 0, type },						\
 | 
			
		||||
		SPA_POD_ID_INIT(media_type),				\
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ spa_pod_builder_push_format(struct spa_pod_builder *builder,
 | 
			
		|||
			    uint32_t media_subtype)
 | 
			
		||||
{
 | 
			
		||||
	const struct spa_format p = SPA_FORMAT_INIT(sizeof(struct spa_format_body),
 | 
			
		||||
					0, format_type, media_type, media_subtype);
 | 
			
		||||
					format_type, media_type, media_subtype);
 | 
			
		||||
	return spa_pod_builder_push(builder, frame, &p.pod,
 | 
			
		||||
				    spa_pod_builder_raw(builder, &p, sizeof(p)));
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue