title: Closing boost::asio::serial_port with pending read_async_some
body: <p>I am chaining <code>read_async_some()</code> calls to asynchronously read from a serial port. At some point, I need to cancel the asynchronous reads using and detect this fact in the associated handlers. From <a href="http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/reference/basic_serial_port/cancel/overload1.html" rel="nofollow">the documentation for <code>cancel()</code></a>, I expected to do so simply by checking the <code>error_code</code> passed to my handlers:</p>
  
  <blockquote>
    <p>This function causes all outstanding asynchronous read or write
    operations to finish immediately, and the handlers for cancelled
    operations will be passed the <code>boost::asio::error::operation_aborted</code> error.</p>
  </blockquote>
  
  <p>However, when I try this, my handlers are called with the <code>invalid_argument</code> error instead of the expected <code>operation_aborted</code> error. Here is a minimal example that reproduces the issue by using a ptty to emulate a serial port:</p>
  
  <pre><code>void handle(boost::system::error_code const&amp; error, size_t count)
  {
      std::cout &lt;&lt; "error_code = " &lt;&lt; error.message() &lt;&lt; std::endl;
  }
  
  int main(int argc, char **argv)
  {
      std::fstream fs("/dev/ttyp0", std::ios::in | std::ios::ate);
      boost::asio::io_service io;
      boost::asio::serial_port serial(io, "/dev/ttyp0");
  
      std::vector&lt;uint8_t&gt; buffer(1);
      serial.async_read_some(boost::asio::buffer(buffer),
          boost::bind(&amp;handle,
                      boost::asio::placeholders::error,
                      boost::asio::placeholders::bytes_transferred
          )
      );
  
      boost::thread thread(boost::bind(&amp;boost::asio::io_service::run, &amp;io));
      serial.cancel();
      thread.join();
      fs.close();
  }
  </code></pre>
  
  <p>At least for me, the output of this program is <code>error_code = Invalid argument</code>. Can anyone explain why I am not getting the behavior described in the documentation?</p>