Currently pulseaudio crashes with an assertion in pa_rtpoll_item_new_asyncmsgq_read() or pa_rtpoll_item_new_asyncmsgq_write() if a loopback is applied to a tunnel-new sink or source, because tunnel-{sink,source}-new do not set thread_info.rtpoll. The same applies to module-combine-sink and module-rtp-recv. This patch is not a complete fix for the problem but provides a temporary band-aid by initializing thread_info.rtpoll properly. The rtpoll created is never run, but loopback and combine-sink nevertheless work, see comments in the code. This patch does not work for module-rtp-recv, but using rtp-recv with a remote sink does not seem to make a lot of sense anyway. Bug link: https://bugs.freedesktop.org/show_bug.cgi?id=73429 --- src/modules/module-tunnel-sink-new.c | 15 +++++++++++++++ src/modules/module-tunnel-source-new.c | 12 ++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c index dd6c8866..7962a5af 100644 --- a/src/modules/module-tunnel-sink-new.c +++ b/src/modules/module-tunnel-sink-new.c @@ -38,6 +38,7 @@ #include <pulsecore/thread.h> #include <pulsecore/thread-mq.h> #include <pulsecore/poll.h> +#include <pulsecore/rtpoll.h> #include <pulsecore/proplist-util.h> #include "module-tunnel-sink-new-symdef.h" @@ -77,6 +78,7 @@ struct userdata { pa_context *context; pa_stream *stream; + pa_rtpoll *rtpoll; bool update_stream_bufferattr_after_connect; @@ -503,6 +505,15 @@ int pa__init(pa_module *m) { goto fail; } + /* The rtpoll created here is never run. It is only necessary to avoid crashes + * when module-tunnel-sink-new is used together with module-loopback or + * module-combine-sink. Both modules base their asyncmsq on the rtpoll provided + * by the sink. module-loopback and combine-sink only work because they call + * pa_asyncmsq_process_one() themselves. module_rtp_recv also uses the rtpoll, + * but never calls pa_asyncmsq_process_one(), so it will not work in combination + * with module-tunnel-sink-new. */ + u->rtpoll = pa_rtpoll_new(); + /* Create sink */ pa_sink_new_data_init(&sink_data); sink_data.driver = __FILE__; @@ -541,6 +552,7 @@ int pa__init(pa_module *m) { /* set thread message queue */ pa_sink_set_asyncmsgq(u->sink, u->thread_mq->inq); + pa_sink_set_rtpoll(u->sink, u->rtpoll); if (!(u->thread = pa_thread_new("tunnel-sink", thread_func, u))) { pa_log("Failed to create thread."); @@ -601,5 +613,8 @@ void pa__done(pa_module *m) { if (u->sink) pa_sink_unref(u->sink); + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + pa_xfree(u); } diff --git a/src/modules/module-tunnel-source-new.c b/src/modules/module-tunnel-source-new.c index 2db928c8..f547911b 100644 --- a/src/modules/module-tunnel-source-new.c +++ b/src/modules/module-tunnel-source-new.c @@ -38,6 +38,7 @@ #include <pulsecore/thread.h> #include <pulsecore/thread-mq.h> #include <pulsecore/poll.h> +#include <pulsecore/rtpoll.h> #include <pulsecore/proplist-util.h> #include "module-tunnel-source-new-symdef.h" @@ -75,6 +76,7 @@ struct userdata { pa_context *context; pa_stream *stream; + pa_rtpoll *rtpoll; bool update_stream_bufferattr_after_connect; bool connected; @@ -502,6 +504,12 @@ int pa__init(pa_module *m) { goto fail; } + /* The rtpoll created here is never run. It is only necessary to avoid crashes + * when module-tunnel-source-new is used together with module-loopback. + * module-loopback bases the asyncmsq on the rtpoll provided by the source and + * only works because it calls pa_asyncmsq_process_one(). */ + u->rtpoll = pa_rtpoll_new(); + /* Create source */ pa_source_new_data_init(&source_data); source_data.driver = __FILE__; @@ -538,6 +546,7 @@ int pa__init(pa_module *m) { u->source->update_requested_latency = source_update_requested_latency_cb; pa_source_set_asyncmsgq(u->source, u->thread_mq->inq); + pa_source_set_rtpoll(u->source, u->rtpoll); if (!(u->thread = pa_thread_new("tunnel-source", thread_func, u))) { pa_log("Failed to create thread."); @@ -598,5 +607,8 @@ void pa__done(pa_module *m) { if (u->source) pa_source_unref(u->source); + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); + pa_xfree(u); } -- 2.11.0