This fixes crashes when trying to use module-rtp-recv or module-combine-sink together with module-tunnel-sink-new. module-rtp-recv and module-combine-sink assume that all IO threads use pa_rtpoll. BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=73429 --- src/modules/module-tunnel-sink-new.c | 35 ++++++++++++++++------------------ src/modules/module-tunnel-source-new.c | 35 ++++++++++++++++------------------ 2 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c index 1b3858d..c8645e3 100644 --- a/src/modules/module-tunnel-sink-new.c +++ b/src/modules/module-tunnel-sink-new.c @@ -74,7 +74,7 @@ struct userdata { pa_sink *sink; pa_thread *thread; pa_thread_mq *thread_mq; - pa_mainloop *thread_mainloop; + pa_rtpoll *rtpoll; pa_mainloop_api *thread_mainloop_api; pa_context *context; @@ -178,13 +178,6 @@ static void thread_func(void *userdata) { for (;;) { int ret; - if (pa_mainloop_iterate(u->thread_mainloop, 1, &ret) < 0) { - if (ret == 0) - goto finish; - else - goto fail; - } - if (PA_UNLIKELY(u->sink->thread_info.rewind_requested)) pa_sink_process_rewind(u->sink, 0); @@ -221,6 +214,14 @@ static void thread_func(void *userdata) { } } + + if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) + goto fail; + + /* ret is zero only when the module is being unloaded, i.e. we're doing + * clean shutdown. */ + if (ret == 0) + goto finish; } fail: pa_asyncmsgq_post(u->thread_mq->outq, PA_MSGOBJECT(u->module->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); @@ -489,18 +490,13 @@ int pa__init(pa_module *m) { u->module = m; m->userdata = u; u->remote_server = pa_xstrdup(remote_server); - u->thread_mainloop = pa_mainloop_new(); - if (u->thread_mainloop == NULL) { - pa_log("Failed to create mainloop"); - goto fail; - } - u->thread_mainloop_api = pa_mainloop_get_api(u->thread_mainloop); + u->rtpoll = pa_rtpoll_new(); + u->thread_mq = pa_xnew0(pa_thread_mq, 1); + pa_thread_mq_init(u->thread_mq, m->core->mainloop, u->rtpoll); + u->thread_mainloop_api = pa_rtpoll_get_mainloop_api(u->rtpoll); u->cookie_file = pa_xstrdup(pa_modargs_get_value(ma, "cookie", NULL)); u->remote_sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); - u->thread_mq = pa_xnew0(pa_thread_mq, 1); - pa_thread_mq_init_thread_mainloop(u->thread_mq, m->core->mainloop, u->thread_mainloop_api); - /* Create sink */ pa_sink_new_data_init(&sink_data); sink_data.driver = __FILE__; @@ -539,6 +535,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."); @@ -584,8 +581,8 @@ void pa__done(pa_module *m) { pa_xfree(u->thread_mq); } - if (u->thread_mainloop) - pa_mainloop_free(u->thread_mainloop); + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); if (u->cookie_file) pa_xfree(u->cookie_file); diff --git a/src/modules/module-tunnel-source-new.c b/src/modules/module-tunnel-source-new.c index c6580eb..64c1066 100644 --- a/src/modules/module-tunnel-source-new.c +++ b/src/modules/module-tunnel-source-new.c @@ -72,7 +72,7 @@ struct userdata { pa_source *source; pa_thread *thread; pa_thread_mq *thread_mq; - pa_mainloop *thread_mainloop; + pa_rtpoll *rtpoll; pa_mainloop_api *thread_mainloop_api; pa_context *context; @@ -227,15 +227,16 @@ static void thread_func(void *userdata) { for (;;) { int ret; - if (pa_mainloop_iterate(u->thread_mainloop, 1, &ret) < 0) { - if (ret == 0) - goto finish; - else - goto fail; - } - if (u->new_data) read_new_samples(u); + + if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) + goto fail; + + /* ret is zero only when the module is being unloaded, i.e. we're doing + * clean shutdown. */ + if (ret == 0) + goto finish; } fail: pa_asyncmsgq_post(u->thread_mq->outq, PA_MSGOBJECT(u->module->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); @@ -488,18 +489,13 @@ int pa__init(pa_module *m) { u->module = m; m->userdata = u; u->remote_server = pa_xstrdup(remote_server); - u->thread_mainloop = pa_mainloop_new(); - if (u->thread_mainloop == NULL) { - pa_log("Failed to create mainloop"); - goto fail; - } - u->thread_mainloop_api = pa_mainloop_get_api(u->thread_mainloop); + u->rtpoll = pa_rtpoll_new(); + u->thread_mq = pa_xnew0(pa_thread_mq, 1); + pa_thread_mq_init(u->thread_mq, m->core->mainloop, u->rtpoll); + u->thread_mainloop_api = pa_rtpoll_get_mainloop_api(u->rtpoll); u->cookie_file = pa_xstrdup(pa_modargs_get_value(ma, "cookie", NULL)); u->remote_source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL)); - u->thread_mq = pa_xnew0(pa_thread_mq, 1); - pa_thread_mq_init_thread_mainloop(u->thread_mq, m->core->mainloop, u->thread_mainloop_api); - /* Create source */ pa_source_new_data_init(&source_data); source_data.driver = __FILE__; @@ -536,6 +532,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."); @@ -581,8 +578,8 @@ void pa__done(pa_module *m) { pa_xfree(u->thread_mq); } - if (u->thread_mainloop) - pa_mainloop_free(u->thread_mainloop); + if (u->rtpoll) + pa_rtpoll_free(u->rtpoll); if (u->cookie_file) pa_xfree(u->cookie_file); -- 1.9.3