Skip to content

Add batch send and recv support #182

@GrapeBaBa

Description

@GrapeBaBa

I am integrating lsquic in our project, it need a user defined send callback function to send the data. In the c++ example, we could see lsquic_out_spec already build the data into iov, but currently xev.UDP.write only could pass slice or array. What is the best approach to use xev.UDP for this case. I thought one approach is transfering the iov copy into a slice and call xev.UDP.write though it need copy data.

api.ea_packets_out = +[](void *void_self,
                             const lsquic_out_spec *out_spec,
                             unsigned n_packets_out) {
      auto self = static_cast<Engine *>(void_self);
      // https://github.com/cbodley/nexus/blob/d1d8486f713fd089917331239d755932c7c8ed8e/src/socket.cc#L218
      int r = 0;
      for (auto &spec : std::span{out_spec, n_packets_out}) {
        msghdr msg{};
        msg.msg_iov = spec.iov;
        msg.msg_iovlen = spec.iovlen;
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast)
        msg.msg_name = const_cast<sockaddr *>(spec.dest_sa);
        msg.msg_namelen = spec.dest_sa->sa_family == AF_INET
                            ? sizeof(sockaddr_in)
                            : sizeof(sockaddr_in6);
        auto n = sendmsg(self->socket_.native_handle(), &msg, 0);
        if (n == -1) {
          if (errno == EAGAIN or errno == EWOULDBLOCK) {
            auto cb = [weak_self{self->weak_from_this()}](
                          boost::system::error_code ec) {
              auto self = weak_self.lock();
              if (not self) {
                return;
              }
              if (ec) {
                return;
              }
              lsquic_engine_send_unsent_packets(self->engine_);
            };
            self->socket_.async_wait(boost::asio::socket_base::wait_write,
                                     std::move(cb));
          }
          break;
        }
        ++r;
      }
      return r;
    };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions