diff options
author | Georg Chini <georg@chini.tk> | 2017-08-12 22:29:26 +0200 |
---|---|---|
committer | Tanu Kaskinen <tanuk@iki.fi> | 2017-08-17 11:40:17 +0300 |
commit | 49ab711c28d5cac6ac4114ecb6477e118f28f720 (patch) | |
tree | d1c11f5f9e698cbfd39c10d9c9e6356889a2bc63 /src | |
parent | 23f46f1d1cbb02301ccfd27bf79219045849d37f (diff) | |
download | pulseaudio-49ab711c28d5cac6ac4114ecb6477e118f28f720.tar.gz |
tunnel-{sink, source}-new: Fix assertion when used with loopback or combine-sink
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
Diffstat (limited to 'src')
-rw-r--r-- | src/modules/module-tunnel-sink-new.c | 15 | ||||
-rw-r--r-- | src/modules/module-tunnel-source-new.c | 12 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c index dd6c8866c..7962a5afa 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 2db928c8d..f547911bf 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); } |