调用async_resolve.cancel(),但async_resolve的回调处理程序不返回boost :: asio :: error :: operation_aborted

时间:2011-06-20 05:49:00

标签: boost boost-asio

我使用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 个答案:

答案 0 :(得分:2)

根据discussion on boost-users邮件列表,resolver::cancel()只能取消待处理的排队解析请求,而不是当前正在执行的请求。

答案 1 :(得分:-1)

作为对@ Cubbi回答的延迟跟进,在这个问题的主题后几个月,Boost issue tracker也提出了这个错误。 Asio解析器API有点令人困惑,因为它表明可以根据需要取消任何async_resolve()操作。我自己也有同样的问题。事实证明,在Asio实现中,对async_resolve()的调用会在后台对getaddrinfo()进行同步系统调用。我在recent codecast中讨论了这个有趣的行为。