pulse-server: use timeout also for creating sample-play streams

Add 35 sec timeout for PLAY_SAMPLE streams to start streaming, similar
to what we do with normal streams, and fail playback if they don't
start.

This avoids pending sample playback using up resources indefinitely if
streams fail to start for some reason, e.g. session manager is not
linking them.
This commit is contained in:
Pauli Virtanen 2026-01-31 15:23:44 +02:00 committed by Wim Taymans
parent a50e9a995e
commit f60e03b4ef
4 changed files with 29 additions and 1 deletions

View file

@ -39,6 +39,8 @@
#define MODULE_INDEX_MASK 0xfffffffu
#define MODULE_FLAG (1u << 29)
#define STREAM_CREATE_TIMEOUT (35 * SPA_NSEC_PER_SEC)
#define DEFAULT_SINK "@DEFAULT_SINK@"
#define DEFAULT_SOURCE "@DEFAULT_SOURCE@"
#define DEFAULT_MONITOR "@DEFAULT_MONITOR@"

View file

@ -17,10 +17,12 @@
#include <pipewire/properties.h>
#include <pipewire/stream.h>
#include "defs.h"
#include "format.h"
#include "log.h"
#include "sample.h"
#include "sample-play.h"
#include "internal.h"
static void sample_play_stream_state_changed(void *data, enum pw_stream_state old,
enum pw_stream_state state, const char *error)
@ -30,17 +32,32 @@ static void sample_play_stream_state_changed(void *data, enum pw_stream_state ol
switch (state) {
case PW_STREAM_STATE_UNCONNECTED:
case PW_STREAM_STATE_ERROR:
pw_timer_queue_cancel(&p->timer);
sample_play_emit_done(p, -EIO);
break;
case PW_STREAM_STATE_PAUSED:
p->id = pw_stream_get_node_id(p->stream);
sample_play_emit_ready(p, p->id);
break;
case PW_STREAM_STATE_STREAMING:
pw_timer_queue_cancel(&p->timer);
break;
default:
break;
}
}
static void sample_play_start_timeout(void *user_data)
{
struct sample_play *p = user_data;
pw_log_info("timeout on sample %s", p->sample->name);
if (p->stream)
pw_stream_set_active(p->stream, false);
sample_play_emit_done(p, -ETIMEDOUT);
}
static void sample_play_stream_destroy(void *data)
{
struct sample_play *p = data;
@ -163,6 +180,10 @@ struct sample_play *sample_play_new(struct pw_core *core,
if (res < 0)
goto error_cleanup;
/* Time out if we don't get a link; same timeout as for normal streams */
pw_timer_queue_add(sample->impl->timer_queue, &p->timer, NULL,
STREAM_CREATE_TIMEOUT, sample_play_start_timeout, p);
return p;
error_cleanup:
@ -181,6 +202,8 @@ void sample_play_destroy(struct sample_play *p)
spa_hook_list_clean(&p->hooks);
pw_timer_queue_cancel(&p->timer);
free(p);
}

View file

@ -11,6 +11,8 @@
#include <spa/utils/list.h>
#include <spa/utils/hook.h>
#include <pipewire/pipewire.h>
struct sample;
struct pw_core;
struct pw_loop;
@ -41,6 +43,7 @@ struct sample_play {
uint32_t offset;
uint32_t stride;
struct spa_hook_list hooks;
struct pw_timer timer;
void *user_data;
};

View file

@ -107,7 +107,7 @@ struct stream *stream_new(struct client *client, enum stream_type type, uint32_t
/* Time out if we don't get a link and can't send a reply to create in 35s. Client will time out in
* 30s and clean up its stream anyway. */
pw_timer_queue_add(stream->impl->timer_queue, &stream->timer, NULL,
35 * SPA_NSEC_PER_SEC, create_stream_timeout, stream);
STREAM_CREATE_TIMEOUT, create_stream_timeout, stream);
return stream;