in wangle/channel/FileRegion.cpp [99:155]
void FileRegion::FileWriteRequest::start() {
started_ = true;
readBase_ = readPool.try_get()->getEventBase();
readBase_->runInEventBaseThread([this] {
auto flags = fcntl(readFd_, F_GETFL);
if (flags == -1) {
fail(
__func__,
AsyncSocketException(
AsyncSocketException::INTERNAL_ERROR,
"fcntl F_GETFL failed",
errno));
return;
}
flags &= O_ACCMODE;
if (flags == O_WRONLY) {
fail(
__func__,
AsyncSocketException(
AsyncSocketException::BAD_ARGS, "file not open for reading"));
return;
}
#ifndef GLIBC_AT_LEAST_2_9
fail(
__func__,
AsyncSocketException(
AsyncSocketException::NOT_SUPPORTED,
"writeFile unsupported on glibc < 2.9"));
return;
#else
int pipeFds[2];
if (::pipe2(pipeFds, O_NONBLOCK) == -1) {
fail(
__func__,
AsyncSocketException(
AsyncSocketException::INTERNAL_ERROR, "pipe2 failed", errno));
return;
}
#ifdef F_SETPIPE_SZ
// Max size for unprevileged processes as set in /proc/sys/fs/pipe-max-size
// Ignore failures and just roll with it
// TODO maybe read max size from /proc?
fcntl(pipeFds[0], F_SETPIPE_SZ, 1048576);
fcntl(pipeFds[1], F_SETPIPE_SZ, 1048576);
#endif
pipe_out_ = pipeFds[0];
socket_->getEventBase()->runInEventBaseThreadAndWait(
[&] { startConsuming(socket_->getEventBase(), &queue_); });
readHandler_ = std::make_unique<FileReadHandler>(this, pipeFds[1], count_);
#endif
});
}