Home > Enterprise >  Why doesn't boost::asio::ip::udp::socket::receive_from throw interruption exception in Windows?
Why doesn't boost::asio::ip::udp::socket::receive_from throw interruption exception in Windows?

Time:09-20

volatile std::sig_atomic_t running = true;

int main()
{
  boost::asio::thread_pool tpool;
  boost::asio::signal_set signals(tpool, SIGINT, SIGTERM);
  signals.async_wait([](auto && err, int) { if (!err) running = false; });

  while(running)
  {
    std::array<std::uint8_t, 1024> data;
    socket.recieve_from(boost::asio::buffer(data), ....); // (1)
    // calc(data);
  }
  return 0;
}

If my code is blocked in the (1) line in Linux and I try raise the signal, for example, with htop then the line (1) throws exception about the interruption but in Windows it doesn't. The problem in what I don't know how to exit the application.

What needs to do my program works equally in both OSs? Thanks.

Use Windows 10 (msvc 17), Debian 11 (gcc-9), Boost 1.78.

CodePudding user response:

Regardless of the question how you "raise the signal" on Windows there's the basic problem that you're relying on OS specifics to cancel a synchronous operation.

Cancellation is an ASIO feature, but only for asynchronous operations. So, consider:

signals.async_wait([&socket](auto&& err, int) {
    if (!err) {
        socket.cancel();
    }
});

Simplifying without a thread_pool gives e.g.:

enter image description here

Multi-threading

There's likely no gain for using multiple threads, but if you do, use a strand to synchronize access to the IO objects:

asio::thread_pool ioc;
Program app(make_strand(ioc));
  • Related