mardi 1 mai 2018

Boost Asio hangs on kqueue

I have the following function that I use to read from a socket:

std::error_code listener::read() noexcept {
  std::error_code error;
  m_data.resize(0);
  m_data.resize(m_header_length);
  asio::async_read(*m_socket, asio::buffer(m_data, m_header_length), asio::transfer_exactly(m_header_length),
                   [&](const std::error_code &ec, const std::size_t size) {
                     if (ec && ec != asio::error::eof) {
                       error = ec;
                       return;
                     }
                     std::size_t available = m_socket->available();
                     std::cerr << available << std::endl;
                     while (available > 0) {
                       std::size_t body_len;
                       if (dbc::db_engine::postgresql == m_params.engine) {
                         // First byte is the packet identifier.
                         body_len = to_number(m_data, true, 1);
                         body_len -= m_header_length - 1;
                       } else {
                         body_len = to_number(m_data, false, 0);
                         ++body_len;
                       }
                       bytes body(body_len);
                       asio::read(*m_socket, asio::buffer(body, body_len), asio::transfer_exactly(body_len));

                       auto it = std::next(body.begin(), body.size());
                       std::move(body.begin(), it, std::back_inserter(m_data));

                       m_on_read_cb(m_data);

                       m_data.resize(0);
                       available = m_socket->available();
                       if (available > 0) {
                         m_data.resize(m_header_length);
                         asio::read(*m_socket, asio::buffer(m_data), asio::transfer_exactly(m_header_length));
                       }
                     }
                   });
  m_service.run(error);
  m_service.reset();
  return error;
}

I'm able to perform a whole authentication handshake with a remote server. I then do a single write, which returns no errors and when I try to read, my method blocks on m_service.run(error);.

Digging deep, it seems to block on the kqueue reactor:

kqueue_reactor.ipp:406:

int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout);

I'm at a loss as to what could be happening as this is completely silent.

Aucun commentaire:

Enregistrer un commentaire