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

Tanu Kaskinen tanu.kaskinen at linux.intel.com
Wed Jan 7 06:56:52 PST 2015


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



More information about the pulseaudio-discuss mailing list