Question

I'm trying to pass data from one UDS to another as quickly as possible in a C++ program, but UDS's don't support splice (as fd_in). Are there any alternative that are supported by UDS's that are as close to zero-copy as possible?

This question was asked for UDP sockets but they never found any alternatives to splice.

Was it helpful?

Solution

Strict Answering Mode

This is a long shot, but I think I remember when the fuse low-level interface gained splice() support.

So, you could implement a fuse driver to do what you want. However, this only makes sense if you insist on having a file-descriptor compatible interface. I suspect it's a non-trivial amount of work, although a project like ntfs-3g might have it implemented.


Thinking Along:

Now, what are you trying to achieve?

In my experience, UNIX domain sockets are only for intra-machine inter-process communication, and chances are that the consumers of the data aren't actually interested in the file/stream nature of the interface.

If it's enough to just pass the data, you perhaps use mmap with splice here:

int fd;
char tmpfile[] = "/tmp/fooXXXXXX";
void *buffer;
int pfd[2];
ssize_t bytes;

fd = mkostemp(tmpfile, O_NOATIME);
unlink(tmpfile);
lseek(fd, 4095, SEEK_SET);
write(fd, "", 1);
lseek(fd, 0, SEEK_SET);
buffer = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE, fd, 0);

pipe(pfd);
bytes = splice(s, NULL, pfd[1], NULL, 4096, SPLICE_F_MOVE);
splice(pfd[0], NULL, fd, NULL, bytes, SPLICE_F_MOVE);

CAUTION: Be aware, when splicing data from a mmap'ed buffer to a network socket, it is not possible to say when all data has been sent. Even if splice() returns, the network stack may not have sent all data yet. So reusing the buffer may overwrite unsent data.

Background information from this HowTo

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top