bool Pair::write()

in gloo/transport/tcp/tls/pair.cc [62:122]


bool Pair::write(Op &op) {
  NonOwningPtr<UnboundBuffer> buf;
  std::array<struct iovec, 2> iov;
  int ioc;

  const auto opcode = op.getOpcode();

  // Acquire pointer to unbound buffer if applicable.
  if (opcode == Op::SEND_UNBOUND_BUFFER) {
    buf = NonOwningPtr<UnboundBuffer>(op.ubuf);
    if (!buf) {
      return false;
    }
  }

  const auto nbytes = prepareWrite(op, buf, iov.data(), ioc);
  ssize_t total_rv = 0;
  for (int i = 0; i < ioc; ++i) {
    for (;;) {
      if (iov[i].iov_len == 0) {
        break;
      }
      ssize_t rv = _glootls::SSL_write(ssl_, iov[i].iov_base, iov[i].iov_len);
      if (rv <= 0) {
        int err = _glootls::SSL_get_error(ssl_, rv);

        GLOO_ENFORCE(err != SSL_ERROR_NONE);
        GLOO_ENFORCE(err != SSL_ERROR_WANT_READ);

        if (err == SSL_ERROR_WANT_WRITE) {
          // just repeat the same write
          continue;
        }

        if (err == SSL_ERROR_SYSCALL) {
          fatal_error_occurred_ = true;
          if (errno == EPIPE) {
            if (!sync_) {
              return false;
            }
          }
        }

        // Unexpected error
        signalException(GLOO_ERROR_MSG(
            "SSL_write ", peer_.str(), " failed: ", "ssl error: ", err,
            ", errno = ", strerror(errno),
            ", ssl error message: ", getSSLErrorMessage()));
        return false;
      }
      total_rv += rv;
      op.nwritten += rv;
      break;
    }
  }
  GLOO_ENFORCE_EQ(total_rv, nbytes);
  GLOO_ENFORCE_EQ(op.nwritten, op.preamble.nbytes);

  writeComplete(op, buf, opcode);
  return true;
}