title: Can a boost::asio::yield_context be used as a deadline_timer handler when doing cancel?
body: <p>I'd like to be able to do an asynchronous wait on a specific event.  There are a lot of similar questions and answers on here (and all compile and work for me) but none with my specific scenario.  Basically, what I need to be able to do is an async_wait, passing a yield context as the handler, to a timer that waits indefinitely, and is then canceled by another thread.</p>
  
  <p>For example, there is <a href="https://stackoverflow.com/questions/17005258/why-does-boost-asio-not-support-an-event-based-interface-for-example-something#" title="this question">this question</a> which does something very similar, but instead of using a yield context, it uses a separate, standalone handler.  There is also something like <a href="https://stackoverflow.com/questions/21771639/can-i-use-a-stackful-coroutine-as-the-wait-handler-of-a-steady-timer-which-is-de" title="this question">this question</a> which uses a yield context, but waits for a specified amount of time.</p>
  
  <p>I can change my code to look like either of the two examples above and things work fine.  But for someone reason when I combine a yield_context handler and a cancelled timer, I get the following exception:</p>
  
  <pre><code>libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl&lt;boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt; &gt;: 
  Program ended with exit code: 9
  </code></pre>
  
  <p>From what I can tell, it looks like things choke when trying to invoke the completion handler (which in this case is the yield context).</p>
  
  <p>Alright, enough babbling, here's the code.  I've tried to come up with as simple of an example as possible to illustrate it:</p>
  
  <p>The class:</p>
  
  <pre><code>class Foo {
  public:
    Foo() : work_(io_service_), timer_(io_service_) {
      thread_pool_.create_thread(boost::bind(&amp;boost::asio::io_service::run, &amp;io_service_));
      timer_.expires_from_now(boost::posix_time::pos_infin);
    }
    ~Foo() {
      io_service_.stop();
      thread_pool_.join_all();
    }
  
    void Wait(const boost::asio::yield_context&amp; context) {
      std::cout &lt;&lt; "Waiting" &lt;&lt; std::endl;
      timer_.async_wait(context);
      std::cout &lt;&lt; "Done waiting" &lt;&lt; std::endl;
    }
  
    void Notify() {
      std::cout &lt;&lt; "Notifying" &lt;&lt; std::endl;
      timer_.cancel();
    }
  
    void Write(int num) {
      std::cout &lt;&lt; "Sending buffer event" &lt;&lt; std::endl;
      Notify();
      std::cout &lt;&lt; "Sent buffer event" &lt;&lt; std::endl;
    }
  
    void Read(const boost::asio::yield_context&amp; context) {
      std::cout &lt;&lt; "Waiting on buffer event, size is " &lt;&lt; buffer_.size() &lt;&lt; std::endl;
      Wait(context);
      std::cout &lt;&lt; "Received buffer event, size is now " &lt;&lt; buffer_.size() &lt;&lt; std::endl;
    }
  
    std::vector&lt;int&gt; buffer_;
    boost::asio::io_service io_service_;
    boost::thread_group thread_pool_;
    boost::asio::io_service::work work_;
    boost::asio::deadline_timer timer_;
  };
  </code></pre>
  
  <p>Main:</p>
  
  <pre><code>boost::shared_ptr&lt;Foo&gt; foo(new Foo());    
  boost::asio::spawn(foo-&gt;io_service_, boost::bind(&amp;Foo::Read, foo, _1));
  boost::this_thread::sleep(boost::posix_time::seconds(2));
  foo-&gt;Write(1);
  boost::this_thread::sleep(boost::posix_time::seconds(4));
  </code></pre>
  
  <p>Output:</p>
  
  <pre><code>Waiting on buffer event
  Waiting
  Sending buffer event
  Notifying
  Sent buffer event
  libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl&lt;boost::exception_detail::current_exception_std_exception_wrapper&lt;std::runtime_error&gt; &gt;: 
  </code></pre>
  
  <p>Now, if I change the wait method to a time that will time out before the cancel is called, everything is fine.  I.e.:</p>
  
  <pre><code>void Wait(const boost::asio::yield_context&amp; context) {
      std::cout &lt;&lt; "Waiting" &lt;&lt; std::endl;
      timer_.expires_from_now(boost::posix_time::seconds(1));
      timer_.async_wait(context);
      std::cout &lt;&lt; "Done waiting" &lt;&lt; std::endl;
    }
  </code></pre>
  
  <p>Or, if I change wait to use a separate handler method, everything is fine.  I.e.:</p>
  
  <pre><code>void Handler() {
    std::cout &lt;&lt; "Handler!" &lt;&lt; std::endl;
  }
  
  void Wait(const boost::asio::yield_context&amp; context) {       
    std::cout &lt;&lt; "Waiting" &lt;&lt; std::endl;
    timer_.async_wait(boost::bind(&amp;Foo::Handler, this));
    std::cout &lt;&lt; "Done waiting" &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>I'm assuming there must be something simpler I'm missing here: either this is impossible for some reason or I'm making some dumb mistake.  Anyway, thanks in advance.</p>