diff --git a/src/pipewire/impl-node.c b/src/pipewire/impl-node.c index f0f947efe..98ab10bb5 100644 --- a/src/pipewire/impl-node.c +++ b/src/pipewire/impl-node.c @@ -1057,6 +1057,9 @@ struct pw_impl_node *pw_context_create_node(struct pw_context *context, this->rt.activation->sync_timeout = DEFAULT_SYNC_TIMEOUT; this->rt.activation->sync_left = 0; + this->rt.rate_limit.interval = 2 * SPA_NSEC_PER_SEC; + this->rt.rate_limit.burst = 1; + check_properties(this); this->driver_node = this; @@ -1358,11 +1361,13 @@ static int node_ready(void *data, int status) uint64_t min_timeout = UINT64_MAX; if (SPA_UNLIKELY(state->pending > 0)) { - pw_log_warn("(%s-%u) graph not finished: state:%p pending %d/%d", + pw_context_driver_emit_incomplete(node->context, node); + if (ratelimit_test(&node->rt.rate_limit, a->signal_time)) { + pw_log_warn("(%s-%u) graph not finished: state:%p pending %d/%d", node->name, node->info.id, state, state->pending, state->required); - pw_context_driver_emit_incomplete(node->context, node); - dump_states(node); + dump_states(node); + } node->rt.target.signal(node->rt.target.data); } diff --git a/src/pipewire/private.h b/src/pipewire/private.h index ae6c08b61..d2e0e70d6 100644 --- a/src/pipewire/private.h +++ b/src/pipewire/private.h @@ -59,6 +59,29 @@ struct defaults { unsigned int mem_allow_mlock; }; +struct ratelimit { + uint64_t interval; + uint64_t begin; + unsigned burst; + unsigned n_printed, n_missed; +}; + +static inline bool ratelimit_test(struct ratelimit *r, uint64_t now) +{ + if (r->begin + r->interval < now) { + if (r->n_missed) + pw_log_warn("%u events suppressed", r->n_missed); + r->begin = now; + r->n_printed = 0; + r->n_missed = 0; + } else if (r->n_printed >= r->burst) { + r->n_missed++; + return false; + } + r->n_printed++; + return true; +} + #define MAX_PARAMS 32 #define pw_protocol_emit_destroy(p) spa_hook_list_call(&p->listener_list, struct pw_protocol_events, destroy, 0) @@ -564,6 +587,8 @@ struct pw_impl_node { struct pw_node_target target; /* our target that is signaled by the driver */ struct spa_list driver_link; /* our link in driver */ + + struct ratelimit rate_limit; } rt; void *user_data; /**< extra user data */