[pulseaudio-discuss] [PATCH 4/8] tunnel*: put sink/source after authentication
Tanu Kaskinen
tanuk at iki.fi
Sun Aug 12 12:05:30 UTC 2018
On Mon, 2018-07-16 at 20:25 -0400, Yclept Nemo wrote:
> Call 'pa_sink_put' or 'pa_source_put' after the connection is
> authorized. For the new tunnel modules this involves sending a
> module-specific message from the IO thread to the main thread. On
> receipt the sink/source message handler calls 'pa_*_put' if connected
> (this doesn't need to by guarded by a conditional; the message should
> only be sent once). For the old tunnel module this involves moving
> 'pa_*_put' down the call chain of the main thread: 'pa__init' ->
> 'on_connection' -> 'setup_complete_callback'.
> ---
> src/modules/module-tunnel-sink-new.c | 14 +++++++++++++-
> src/modules/module-tunnel-source-new.c | 14 +++++++++++++-
> src/modules/module-tunnel.c | 12 ++++++------
> 3 files changed, 32 insertions(+), 8 deletions(-)
>
> diff --git a/src/modules/module-tunnel-sink-new.c b/src/modules/module-tunnel-sink-new.c
> index 802e6a59..b301f999 100644
> --- a/src/modules/module-tunnel-sink-new.c
> +++ b/src/modules/module-tunnel-sink-new.c
> @@ -60,6 +60,10 @@ PA_MODULE_USAGE(
> #define MAX_LATENCY_USEC (200 * PA_USEC_PER_MSEC)
> #define TUNNEL_THREAD_FAILED_MAINLOOP 1
>
> +enum {
> + SINK_MESSAGE_PUT = PA_SINK_MESSAGE_MAX,
> +};
> +
> static void stream_state_cb(pa_stream *stream, void *userdata);
> static void stream_changed_buffer_attr_cb(pa_stream *stream, void *userdata);
> static void stream_set_buffer_attr_cb(pa_stream *stream, int success, void *userdata);
> @@ -345,6 +349,7 @@ static void context_state_cb(pa_context *c, void *userdata) {
> u->thread_mainloop_api->quit(u->thread_mainloop_api, TUNNEL_THREAD_FAILED_MAINLOOP);
> }
> u->connected = true;
> + pa_asyncmsgq_send(u->thread_mq->outq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_PUT, NULL, 0, NULL);
pa_asyncmsgq_send() is synchronous, and it shouldn't be used from the
IO thread, because that can cause deadlocks. I think an asynchronous
message would work fine in this case (i.e. pa_asyncmsgq_post()).
> break;
> }
> case PA_CONTEXT_FAILED:
> @@ -402,6 +407,7 @@ static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t of
> struct userdata *u = PA_SINK(o)->userdata;
>
> switch (code) {
> + /* Delivered from the main thread, handled in the IO thread. */
> case PA_SINK_MESSAGE_GET_LATENCY: {
> int negative;
> pa_usec_t remote_latency;
> @@ -429,6 +435,13 @@ static int sink_process_msg_cb(pa_msgobject *o, int code, void *data, int64_t of
> *((int64_t*) data) = remote_latency;
> return 0;
> }
> +
> + /* Delivered from the IO thread, handled in the main thread. */
> + case SINK_MESSAGE_PUT: {
> + if (u->connected)
> + pa_sink_put(u->sink);
u->connected is supposed to be used only in the IO thread. In what
situation would you want to not put the sink? I suppose at least during
module unloading it could happen that the SINK_MESSAGE_PUT message is
processed, but we don't want to call pa_sink_put().
A separate flag could be set in the beginning of pa__done() to indicate
that the module is being unloaded, but I think it would make sense to
have that flag in the core pa_module struct instead, and set it in
pa_module_free(). There's already pa_module.unload_requested, which is
kind of what we want, but it's currently only set if
pa_module_unload_request() is called. I think
pa_module.unload_requested could be set also from pa_module_free(), and
then it would be a reliable flag for checking whether the module is
being unloaded.
--
Tanu
https://www.patreon.com/tanuk
https://liberapay.com/tanuk
More information about the pulseaudio-discuss
mailing list