mercredi 26 octobre 2016

Heisenbug when doing an ansychronous read from socket

I'm calling async_read on a domain socket and my problem is that sometimes I get data and sometimes I don't, even though the remote system always returns data. I seem to be able to read from the socket if I do step-by-step debugging. If I automate unit tests they seem to run too fast for data to be returned, which is odd since the whole purpose of asynchronous methods is to wait for a reply.

I have these as properties of my class:

io_service run_loop;
stream_protocol::socket connection_socket;
datagram_protocol::endpoint domain_socket_ep;
vector<unsigned char>read_buffer;

I do a write:

void operator>>(const vector<unsigned char> input, shared_ptr<Socket>socket) {
  asio::async_write(socket->connection_socket, asio::buffer(input),   std::bind(&Socket::write_handler, socket, std::placeholders::_1, std::placeholders::_2));
  socket->run_loop.reset();
  socket->run_loop.run();
}

In the write callback I do a read:

void Socket::write_handler(const std::error_code &ec, const size_t size) noexcept {
  const size_t avail = connection_socket.available();
  if (!read_buffer.empty()) {
    read_buffer.clear();
  }
  asio::async_read(connection_socket, asio::buffer(read_buffer, avail), std::bind(&Socket::read_handler, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}

I tried wrapping the read function in a while(read_buffer.size() < avail) but that just threw me into an infinite loop.

I'm definitely missing something here, I just can't figure out what and the fact that this works when running under step-by-step just makes it worse.

Aucun commentaire:

Enregistrer un commentaire