diff --git a/pipewire/client/connection.c b/pipewire/client/connection.c index 3823ecdf9..c6e36af0b 100644 --- a/pipewire/client/connection.c +++ b/pipewire/client/connection.c @@ -25,12 +25,17 @@ #include #include +#include + +#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); } diff --git a/pipewire/client/context.c b/pipewire/client/context.c index e30d55ca8..9008a0b3b 100644 --- a/pipewire/client/context.c +++ b/pipewire/client/context.c @@ -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); diff --git a/pipewire/client/introspect.c b/pipewire/client/introspect.c index af10b77ac..9b7c42d9b 100644 --- a/pipewire/client/introspect.c +++ b/pipewire/client/introspect.c @@ -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); diff --git a/pipewire/client/log.c b/pipewire/client/log.c index 1b54a0685..041c95ecf 100644 --- a/pipewire/client/log.c +++ b/pipewire/client/log.c @@ -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); diff --git a/pipewire/client/loop.c b/pipewire/client/loop.c index 3242850d9..b64a6d775 100644 --- a/pipewire/client/loop.c +++ b/pipewire/client/loop.c @@ -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); diff --git a/pipewire/client/pipewire.c b/pipewire/client/pipewire.c index a32c9ee21..440e29908 100644 --- a/pipewire/client/pipewire.c +++ b/pipewire/client/pipewire.c @@ -18,12 +18,28 @@ */ #include +#include #include #include #include #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) diff --git a/pipewire/client/pipewire.h b/pipewire/client/pipewire.h index 39a2ddddd..2c2db9d3b 100644 --- a/pipewire/client/pipewire.h +++ b/pipewire/client/pipewire.h @@ -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); diff --git a/pipewire/client/proxy.c b/pipewire/client/proxy.c index e04d17647..e44b0b82b 100644 --- a/pipewire/client/proxy.c +++ b/pipewire/client/proxy.c @@ -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); } diff --git a/pipewire/client/proxy.h b/pipewire/client/proxy.h index 61b9ea4fb..95b7b7b7e 100644 --- a/pipewire/client/proxy.h +++ b/pipewire/client/proxy.h @@ -27,6 +27,7 @@ extern "C" { #include #include #include +#include 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)); }; diff --git a/pipewire/client/utils.h b/pipewire/client/utils.h index e5746e71d..7a339f903 100644 --- a/pipewire/client/utils.h +++ b/pipewire/client/utils.h @@ -27,6 +27,8 @@ extern "C" { #include #include +typedef void (*pw_destroy_t) (void *object); + const char * pw_split_walk(const char *str, const char *delimiter, size_t *len, const char **state); diff --git a/pipewire/server/resource.h b/pipewire/server/resource.h index cdb137dc1..8b4d97613 100644 --- a/pipewire/server/resource.h +++ b/pipewire/server/resource.h @@ -32,8 +32,6 @@ extern "C" { #include #include -typedef void (*pw_destroy_t) (void *object); - struct pw_resource { struct pw_core *core; struct spa_list link; diff --git a/spa/include/spa/format-builder.h b/spa/include/spa/format-builder.h index 47dda0418..fc4308048 100644 --- a/spa/include/spa/format-builder.h +++ b/spa/include/spa/format-builder.h @@ -29,7 +29,7 @@ extern "C" { #include #include -#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))); }