summaryrefslogtreecommitdiff
path: root/src/pulsecore
diff options
context:
space:
mode:
Diffstat (limited to 'src/pulsecore')
-rw-r--r--src/pulsecore/core.c9
-rw-r--r--src/pulsecore/core.h2
-rw-r--r--src/pulsecore/protocol-native.c49
3 files changed, 45 insertions, 15 deletions
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index 56cbe9df0..6d102f58a 100644
--- a/src/pulsecore/core.c
+++ b/src/pulsecore/core.c
@@ -61,16 +61,19 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o
static void core_free(pa_object *o);
-pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size) {
+pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t shm_size) {
pa_core* c;
pa_mempool *pool;
+ pa_mem_type_t type;
int j;
pa_assert(m);
if (shared) {
- if (!(pool = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, shm_size, false))) {
- pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal memory pool.");
+ type = (enable_memfd) ? PA_MEM_TYPE_SHARED_MEMFD : PA_MEM_TYPE_SHARED_POSIX;
+ if (!(pool = pa_mempool_new(type, shm_size, false))) {
+ pa_log_warn("Failed to allocate %s memory pool. Falling back to a normal memory pool.",
+ pa_mem_type_to_string(type));
shared = false;
}
}
diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h
index 9f5c44532..1a3c4902e 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -218,7 +218,7 @@ enum {
PA_CORE_MESSAGE_MAX
};
-pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size);
+pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t shm_size);
/* Check whether no one is connected to this core */
void pa_core_check_idle(pa_core *c);
diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c
index 566ba6f1e..5619b9c20 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2598,7 +2598,7 @@ static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */
}
-static void setup_srbchannel(pa_native_connection *c) {
+static void setup_srbchannel(pa_native_connection *c, pa_mem_type_t shm_type) {
pa_srbchannel_template srbt;
pa_srbchannel *srb;
pa_memchunk mc;
@@ -2631,20 +2631,25 @@ static void setup_srbchannel(pa_native_connection *c) {
return;
}
- if (!(c->rw_mempool = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, c->protocol->core->shm_size, true))) {
+ if (!(c->rw_mempool = pa_mempool_new(shm_type, c->protocol->core->shm_size, true))) {
pa_log_warn("Disabling srbchannel, reason: Failed to allocate shared "
"writable memory pool.");
return;
}
+
+ if (shm_type == PA_MEM_TYPE_SHARED_MEMFD) {
+ const char *reason;
+ if (pa_pstream_register_memfd_mempool(c->pstream, c->rw_mempool, &reason)) {
+ pa_log_warn("Disabling srbchannel, reason: Failed to register memfd mempool: %s", reason);
+ goto fail;
+ }
+ }
pa_mempool_set_is_remote_writable(c->rw_mempool, true);
srb = pa_srbchannel_new(c->protocol->core->mainloop, c->rw_mempool);
if (!srb) {
pa_log_debug("Failed to create srbchannel");
-
- pa_mempool_unref(c->rw_mempool);
- c->rw_mempool = NULL;
- return;
+ goto fail;
}
pa_log_debug("Enabling srbchannel...");
pa_srbchannel_export(srb, &srbt);
@@ -2664,6 +2669,13 @@ static void setup_srbchannel(pa_native_connection *c) {
pa_pstream_send_memblock(c->pstream, 0, 0, 0, &mc);
c->srbpending = srb;
+ return;
+
+fail:
+ if (c->rw_mempool) {
+ pa_mempool_unref(c->rw_mempool);
+ c->rw_mempool = NULL;
+ }
}
static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
@@ -2682,7 +2694,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;
+ bool memfd_on_remote = false, do_memfd = false;
pa_tagstruct *reply;
pa_mem_type_t shm_type;
bool shm_on_remote = false, do_shm;
@@ -2777,7 +2789,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
}
}
- /* Enable shared memory support if possible */
+ /* Enable shared memory and memfd support if possible */
do_shm =
pa_mempool_is_shared(c->protocol->core->mempool) &&
c->is_local;
@@ -2803,9 +2815,12 @@ 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);
+ do_memfd =
+ do_shm && pa_mempool_is_memfd_backed(c->protocol->core->mempool);
+
shm_type = PA_MEM_TYPE_PRIVATE;
if (do_shm) {
- if (c->version >= 31 && memfd_on_remote && pa_memfd_is_locally_supported()) {
+ if (c->version >= 31 && memfd_on_remote && do_memfd) {
pa_pstream_enable_memfd(c->pstream);
shm_type = PA_MEM_TYPE_SHARED_MEMFD;
} else
@@ -2817,7 +2832,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
reply = reply_new(tag);
pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION | (do_shm ? 0x80000000 : 0) |
- (pa_memfd_is_locally_supported() ? 0x40000000 : 0));
+ (do_memfd ? 0x40000000 : 0));
#ifdef HAVE_CREDS
{
@@ -2834,7 +2849,19 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
pa_pstream_send_tagstruct(c->pstream, reply);
#endif
- setup_srbchannel(c);
+ /* The client enables memfd transport on its pstream only after
+ * inspecting our version flags to see if we support memfds too.
+ *
+ * Thus register any pools after sending the server's version
+ * flags and _never_ before it. */
+ if (shm_type == PA_MEM_TYPE_SHARED_MEMFD) {
+ const char *reason;
+
+ if (pa_pstream_register_memfd_mempool(c->pstream, c->protocol->core->mempool, &reason))
+ pa_log("Failed to register memfd mempool. Reason: %s", reason);
+ }
+
+ setup_srbchannel(c, shm_type);
}
static void command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {