diff --git a/src/modules/module-protocol-pulse/defs.h b/src/modules/module-protocol-pulse/defs.h index c333f21f5..f3e25f137 100644 --- a/src/modules/module-protocol-pulse/defs.h +++ b/src/modules/module-protocol-pulse/defs.h @@ -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@" diff --git a/src/modules/module-protocol-pulse/sample-play.c b/src/modules/module-protocol-pulse/sample-play.c index db3893c0f..09b0e75cc 100644 --- a/src/modules/module-protocol-pulse/sample-play.c +++ b/src/modules/module-protocol-pulse/sample-play.c @@ -17,10 +17,12 @@ #include #include +#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); } diff --git a/src/modules/module-protocol-pulse/sample-play.h b/src/modules/module-protocol-pulse/sample-play.h index a34ca9213..98af7ee29 100644 --- a/src/modules/module-protocol-pulse/sample-play.h +++ b/src/modules/module-protocol-pulse/sample-play.h @@ -11,6 +11,8 @@ #include #include +#include + 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; }; diff --git a/src/modules/module-protocol-pulse/stream.c b/src/modules/module-protocol-pulse/stream.c index 496bcb52c..a6beb9fd7 100644 --- a/src/modules/module-protocol-pulse/stream.c +++ b/src/modules/module-protocol-pulse/stream.c @@ -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;