void FileRegion::FileWriteRequest::start()

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
  });
}