mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-29 05:40:23 -04:00
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
This commit is contained in:
parent
23f46f1d1c
commit
49ab711c28
2 changed files with 27 additions and 0 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue