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);