2011-06-20 5 views
0

私は、async_resolveがコールバックを呼び出さないように、http requestおよびanswerを処理するためにboost asioを使用しました。解決タイムアウトが、私はhandle_resolve_timeoutが呼び出されたが、handle_resolveはブーストを返しません:: ASIO ::エラー:: operation_aborted、なぜ、私際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"); 
    } 
} 

:ハンドラ、私はちょうどこのように、タイムアウトを設定しました誰かが私のためにそれを説明することができますか?

答えて

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で議論します。

関連する問題