sockpp icon indicating copy to clipboard operation
sockpp copied to clipboard

Scatter/gather I/O (like readv/writev)

Open snej opened this issue 4 years ago • 2 comments

For performance reasons it's good to be able to read or write multiple discontiguous byte ranges in one system call. The generic system calls for this are writev and readv; the socket-specific ones are sendmsg and recvmsg.

The C++ methods for these would probably take a const std::vector<iovec>& parameter.

snej avatar Sep 09 '19 17:09 snej

I started this for Linux and hadn't even looked to see if there was a portable API for Windows or if I would need to fake it. I will look into sendmsg and recvmsg.

I was also wondering what to do about short returns... if the call didn't transfer all the requested data in or out. Keeping with the philosophy of the thin wrapper, the basic call should do this. But could/should we come up with an equivalent to readn() & writen() for scatter gather (keep retrying until done).

It's a tough call, since a retry would break the atomic promise of the base call. (At least that's how it works in Linux).

fpagliughi avatar Sep 09 '19 17:09 fpagliughi

This is coming along, but the implementation seems to require a bit too much ugly boilerplate. Doing an output for a payload, header, and footer (as strings) looks something like this:

std::string str { "This is a test" };

const std::string HEADER { "<start>" },
                  FOOTER { "<end>" };

std::vector<iovec> outv {
    iovec { (void*) HEADER.data(), HEADER.length() },
    iovec { (void*) str.data(), str.length() },
    iovec { (void*) FOOTER.data(), FOOTER.length() }
};

ssock.write(outv);

It may be worth putting together an iovec_collection class, or something like that. It would just be able to construct the vector of iovec objects without thr ugly, manual build, like:

iovec_collection outv { HEADER, str, FOOTER };
ssock.write(outv);

fpagliughi avatar Oct 04 '19 17:10 fpagliughi