вызовите async_resolve.cancel (), но обработчик обратного вызова async_resolve не возвращает boost :: asio :: error :: operation_aborted - PullRequest
0 голосов
/ 20 июня 2011

я использовал boost asio для обработки http-запроса и ответа, чтобы async_resolve не вызывал его обработчик обратного вызова, я установил тайм-аут, вот так:

void resolve()
{
  resolver_.async_resolve(query,strand_.wrap(boost::bind(&connection::handle_resolve,
                          shared_from_this(),
                          boost::asio::placeholders::error,
                          boost::asio::placeholders::iterator)));
  int cancel_num = timer_.expires_from_now(boost::posix_time::seconds(resolve_timeout_));
  timer_.async_wait(strand_.wrap(boost::bind(&connection::handle_resolve_timeout,
                    shared_from_this(),
                    boost::asio::placeholders::error)));
}


void connection::handle_resolve_timeout(const boost::system::error_code& err)
{
  if (err != boost::asio::error::operation_aborted)
  {
      resolver_.cancel();
  }
}

void connection::handle_resolve(const boost::system::error_code& err,
                    boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
{
  timer_.cancel();
  if(!err)
  {
    boost::asio::ip::tcp::endpoint endpoint = *endpoint_iterator;
    socket_.async_connect(endpoint,strand_.wrap(boost::bind(&connection::handle_connect,
                  shared_from_this(),
                  boost::asio::placeholders::error,
                  ++endpoint_iterator)));
    //to distinct the type of timeout ,0:connect timeout,1:read timeout
    int flag = 0;
    int cancel_num = timer_.expires_from_now(boost::posix_time::seconds(connect_timeout_));
    timer_.async_wait(strand_.wrap(boost::bind(&connection::handle_timeout,
                      shared_from_this(),
                      boost::asio::placeholders::error,
                      flag)));
  }
  else if(err != boost::asio::error::operation_aborted)
  {
    status_ = resolve_error;
    check_.do_finish(shared_from_this());
  }
  else
  {
    FASTCHECK_INFO("resolve is canceled\n");
  }
}

при разрешении тайм-аута я обнаружил, что handle_resolve_timeout вызывается, но handle_resolve не возвращает boost :: asio :: error :: operation_aborted. Почему, я озадачен, может кто-нибудь объяснить это мне?

Ответы [ 2 ]

2 голосов
/ 20 июня 2011

В соответствии с дискуссией о рассылке пользователей Boost-Users , resolver::cancel() может отменить только ожидающие запросы, находящиеся в очереди, но не тот, который выполняется в данный момент.

0 голосов
/ 02 августа 2017

В качестве отложенного ответа на ответ @ Cubbi эта ошибка была также обнаружена на трекере проблем Boost через несколько месяцев после ветки этого вопроса.API распознавателя Asio немного сбивает с толку, поскольку предполагает, что любая операция async_resolve() может быть отменена по требованию.У меня была такая же проблема сама.Также оказывается, что в реализации Asio вызовы async_resolve() делают синхронный системный вызов getaddrinfo() за кадром.Я обсуждаю это интересное поведение в недавней кодовой трансляции .

...