diff options
author | Ahmed S. Darwish <darwish.07@gmail.com> | 2016-06-16 10:27:37 +0200 |
---|---|---|
committer | Arun Raghavan <arun@arunraghavan.net> | 2016-06-22 21:04:47 +0530 |
commit | 87f437d0ddbf16312130f72385c901b28ba980b6 (patch) | |
tree | 2a46ab00aa13538e1fa52e16f33f4bb12a13d398 /src | |
parent | 06fbdcaa3ecdd733b52e66976ec39893d1e53fe0 (diff) |
pstream: Add rationale for pa_cmsg_ancil_data_close_fds()
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/pulsecore/pstream.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/pulsecore/pstream.c b/src/pulsecore/pstream.c index 2c9e4523e..3b94a3adf 100644 --- a/src/pulsecore/pstream.c +++ b/src/pulsecore/pstream.c @@ -186,9 +186,34 @@ struct pa_pstream { }; #ifdef HAVE_CREDS -/* Don't close the ancillary fds by your own! Always call this method; - * it guarantees necessary cleanups after fds close.. This method is - * also multiple-invocations safe. */ +/* + * memfd-backed SHM pools blocks transfer occur without passing the pool's + * fd every time, thus minimizing overhead and avoiding fd leaks. A + * REGISTER_MEMFD_SHMID command is sent, with the pool's memfd fd, very early + * on. This command has an ID that uniquely identifies the pool in question. + * Further pool's block references can then be exclusively done using such ID; + * the fd can be safely closed – on both ends – afterwards. + * + * On the sending side of this command, we want to close the passed fds + * directly after being sent. Meanwhile we're only allowed to asynchronously + * schedule packet writes to the pstream, so the job of closing passed fds is + * left to the pstream's actual writing function do_write(): it knows the + * exact point in time where the fds are passed to the other end through + * iochannels and the sendmsg() system call. + * + * Nonetheless not all code paths in the system desire their socket-passed + * fds to be closed after the send. srbchannel needs the passed fds to still + * be open for further communication. System-wide global memfd-backed pools + * also require the passed fd to be open: they pass the same fd, with the same + * ID registration mechanism, for each newly connected client to the system. + * + * So from all of the above, never close the ancillary fds by your own and + * always call below method instead. It takes care of closing the passed fds + * _only if allowed_ by the code paths that originally created them to do so. + * Moreover, it is multiple-invocations safe: failure handlers can, and + * should, call it for passed fds cleanup without worrying too much about + * the system state. + */ void pa_cmsg_ancil_data_close_fds(struct pa_cmsg_ancil_data *ancil) { if (ancil && ancil->nfd > 0 && ancil->close_fds_on_cleanup) { int i; |