[pulseaudio-discuss] [PATCH 5/5] tunnel-new: Replace pa_mainloop with pa_rtpoll

Arun Raghavan arun at accosted.net
Tue Feb 9 11:23:52 CET 2016


On Fri, 2015-01-02 at 15:04 +0200, Tanu Kaskinen wrote:
> 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
> ---

Looks good to me.

-- Arun

>  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 7d3bd99..cbb721f 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;
> @@ -169,13 +169,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);
>  
> @@ -212,6 +205,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);
> @@ -480,18 +481,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__;
> @@ -530,6 +526,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.");
> @@ -575,8 +572,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);


More information about the pulseaudio-discuss mailing list