2011-06-20 48 views
0

我使用boost asio來處理http請求和應答,以避免async_resolve不調用其回調函數處理程序,我設置了超時,就像這樣:調用async_resolve.cancel(),但async_resolve的回調處理程序不會返回boost :: asio :: error :: operation_aborted

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 ::錯誤:: operation_aborted,爲什麼,我我感到困惑,有人能爲我解釋嗎?

回答

2

根據discussion on boost-users郵件列表,resolver::cancel()只能取消掛起的排隊解析請求,而不是當前正在執行的解析請求。

+0

是的,我嘗試設置resolve_timeout = 10s或1s,然後在handle_resolve_timeout中調用cancel,但handle_resolve在幾秒鐘後仍然會被調用,沒有boost :: asio :: error :: operation_aborted錯誤,我認爲你是對的,也許handle_resolve在resolve :: cancel被調用之前設置爲uncancel狀態,所以取消不起作用,但async_connect或async_read_XX並非如此。謝謝你,這是唯一的解釋。 –

0

作爲@ Cubbi回答的延遲後續操作,這個問題在Boost issue tracker這個問題的主題後幾個月也被提出。 Asio解析器API稍有混淆,因爲它暗示任何async_resolve()操作都可以根據需要取消。我自己也有同樣的問題。事實也證明,在Asio實施中,呼叫async_resolve()在幕後對getaddrinfo()進行同步系統調用。我在recent codecast討論這個有趣的行爲。

相關問題