如果还有异步操作等待basic_waitable_timer被破坏怎么办?

时间:2014-10-16 06:02:09

标签: c++ boost boost-asio

如果还有异步操作等待basic_waitable_timer被破坏怎么办?行为是否记录在任何地方?

2 个答案:

答案 0 :(得分:7)

当IO对象(例如basic_waitable_timer)被销毁时,其destructor将在IO对象的服务上调用destroy()(不要与io_service混淆) ,传递IO对象的实现。 basic_waitable_timer的服务为waitable_timer_service,符合WaitableTimerService类型要求。 WaitableTimerService的要求定义destroy()取消异步等待操作的后置条件,使它们尽快完成,并且取消操作的处理程序将传递错误代码boost::asio::error::operation_aborted

  

service.destroy(impl);→隐式取消异步等待操作,就像调用service.cancel(impl, e)一样。

     

service.cancel(impl, e);→导致任何未完成的异步等待操作尽快完成。取消操作的处理程序应传递错误代码error::operation_aborted。设置e表示成功或失败。

请注意,已排队等待调用的操作的处理程序将不会被取消,并且将具有反映操作成功的error_code


以下是完整示例demonstrating此行为:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>

void demo_deferred_completion()
{
  std::cout << "[demo deferred completion]" << std::endl;
  boost::asio::io_service io_service;
  auto wait_completed = false;

  // Use scope to force lifetime.  
  {
    // Create the timer and initiate an async_wait operation that
    // is guaranteed to have expired.
    boost::asio::steady_timer timer(io_service);

    // Post a ready-to-run no-op completion handler into the io_service.
    // Although the order is unspecified, the current implementation
    // will use a predictable order.
    io_service.post([]{});

    // Initiate an async_wait operation that will immediately expire.
    timer.expires_at(boost::asio::steady_timer::clock_type::now());
    timer.async_wait(
        [&](const boost::system::error_code& error)
        {
          std::cout << "error: " << error.message() << std::endl;
          assert(error == boost::system::error_code()); // Success.
          wait_completed = true;          
        });

    // While this will only run one handler (the noop), it will
    // execute operations (async_wait), and if they are succesful
    // (time expired), the completion handler will be posted for
    // deferred completion.
    io_service.run_one();
    assert(!wait_completed); // Verify the wait handler was not invoked.
  } // Destroy the timer.

  // Run the handle_wait completion handler.
  io_service.run();
  assert(wait_completed);
}

void demo_cancelled()
{
  std::cout << "[demo cancelled]" << std::endl;
  boost::asio::io_service io_service;

  // Use scope to force lifetime.
  {
    boost::asio::steady_timer timer(io_service);

    // Initiate an async_wait operation that will immediately expire.
    timer.expires_at(boost::asio::steady_timer::clock_type::now());
    timer.async_wait(
        [](const boost::system::error_code& error)
        {
          std::cout << "error: " << error.message() << std::endl;
          assert(error ==
                 make_error_code(boost::asio::error::operation_aborted));
        });
  } // Destroy the timer.

  // Run the handle_wait completion handler.
  io_service.run();
}

int main()
{
  demo_deferred_completion();
  demo_cancelled();
}

输出:

[demo deferred completion]
error: Success
[demo cancelled]
error: Operation canceled

答案 1 :(得分:2)

它将被取消:使用error_code operation_aborted

调用完成处理程序

相关背景资料:boost::asio async handlers invoked without error after cancellation