Use memfd blocks for the srbchannel if: - we have memfd support compiled in, and .. - client supports PA protocol version >= 31, and .. - client states that it can handle memfd shared memory Otherwise fall-back to the regular Posix shm_open() techniques. Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com> --- PROTOCOL | 15 +++++++++++++++ configure.ac | 2 +- src/pulse/context.c | 2 ++ src/pulsecore/protocol-native.c | 31 ++++++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/PROTOCOL b/PROTOCOL index 3c08fea..e7fdda7 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -371,6 +371,21 @@ PA_COMMAND_DISABLE_SRBCHANNEL Tells the client to stop listening on the additional SHM ringbuffer channel. Acked by client by sending PA_COMMAND_DISABLE_SRBCHANNEL back. +## v31, implemented by >= 7.0 + +PA_COMMAND_AUTH + +New field, from client to server, specifying whether the client supports +using memfd shared memory. + +The server will use memfd communication if: + +- the server has memfd code compiled in, and .. +- client supports protocol version >= 31, and .. +- the client states that it can handle memfd shared memory + +Otherwise, regular posix SHM is used. + #### If you just changed the protocol, read this ## module-tunnel depends on the sink/source/sink-input/source-input protocol ## internals, so if you changed these, you might have broken module-tunnel. diff --git a/configure.ac b/configure.ac index cee1bb4..85807ab 100644 --- a/configure.ac +++ b/configure.ac @@ -40,7 +40,7 @@ AC_SUBST(PA_MINOR, pa_minor) AC_SUBST(PA_MAJORMINOR, pa_major.pa_minor) AC_SUBST(PA_API_VERSION, 12) -AC_SUBST(PA_PROTOCOL_VERSION, 30) +AC_SUBST(PA_PROTOCOL_VERSION, 31) # The stable ABI for client applications, for the version info x:y:z # always will hold y=z diff --git a/src/pulse/context.c b/src/pulse/context.c index ede01fa..f272cd6 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -591,6 +591,8 @@ static void setup_context(pa_context *c, pa_iochannel *io) { pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0)); pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie)); + pa_tagstruct_put_boolean(t, pa_memfd_is_supported()); + #ifdef HAVE_CREDS { pa_creds ucred; diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 87d3c01..042f1cd 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -55,6 +55,7 @@ #include <pulsecore/core-util.h> #include <pulsecore/ipacl.h> #include <pulsecore/thread-mq.h> +#include <pulsecore/memfd.h> #include "protocol-native.h" @@ -172,6 +173,7 @@ struct pa_native_connection { bool authorized:1; bool is_local:1; uint32_t version; + pa_mem_type_t shm_type; pa_client *client; pa_pstream *pstream; pa_pdispatch *pdispatch; @@ -2607,7 +2609,7 @@ static void setup_srbchannel(pa_native_connection *c) { return; } - if (!(rw_mempool = pa_mempool_new(PA_MEMORY_SHARED_POSIX, c->protocol->core->shm_size))) { + if (!(rw_mempool = pa_mempool_new(c->shm_type, c->protocol->core->shm_size))) { pa_log_warn("Disabling srbchannel, reason: Failed to allocate shared " "writable memory pool."); return; @@ -2658,6 +2660,7 @@ static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32 static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const void*cookie; + bool memfd_on_remote = false; pa_tagstruct *reply; bool shm_on_remote = false, do_shm; @@ -2665,8 +2668,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta pa_assert(t); if (pa_tagstruct_getu32(t, &c->version) < 0 || - pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0 || - !pa_tagstruct_eof(t)) { + pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0) { protocol_error(c); return; } @@ -2685,6 +2687,18 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta c->version &= 0x7FFFFFFFU; } + if (c->version < 31) { + if (!pa_tagstruct_eof(t)) { + protocol_error(c); + return; + } + } else { + if (pa_tagstruct_get_boolean(t, &memfd_on_remote) < 0 || !pa_tagstruct_eof(t)) { + protocol_error(c); + return; + } + } + pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION); pa_proplist_setf(c->client->proplist, "native-protocol.version", "%u", c->version); @@ -2769,6 +2783,17 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta pa_log_debug("Negotiated SHM: %s", pa_yes_no(do_shm)); pa_pstream_enable_shm(c->pstream, do_shm); + c->shm_type = PA_MEMORY_UNDEFINED; + if (do_shm) { + if (c->version >= 31 && memfd_on_remote && pa_memfd_is_supported()) + c->shm_type = PA_MEMORY_SHARED_MEMFD; + else + c->shm_type = PA_MEMORY_SHARED_POSIX; + + pa_log_debug("Memfd possible: %s", pa_yes_no(pa_memfd_is_supported())); + pa_log_debug("Negotiated SHM type: %s", pa_mem_type_tostr(c->shm_type)); + } + reply = reply_new(tag); pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION | (do_shm ? 0x80000000 : 0)); -- Darwish http://darwish.chasingpointers.com