[Boost-bugs] [Boost C++ Libraries] #8722: The boost::asio::windows::stream_handle::read_some method may (incorrectly) throw when used with named-pipes in message mode (on Windows) and receives an ERROR_MORE_DATA error

Subject: [Boost-bugs] [Boost C++ Libraries] #8722: The boost::asio::windows::stream_handle::read_some method may (incorrectly) throw when used with named-pipes in message mode (on Windows) and receives an ERROR_MORE_DATA error
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-06-24 12:20:04


#8722: The boost::asio::windows::stream_handle::read_some method may (incorrectly)
throw when used with named-pipes in message mode (on Windows) and receives
an ERROR_MORE_DATA error
----------------------------------------+----------------------------
 Reporter: Dentcho Bankov <dbankov@…> | Owner: chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost Development Trunk | Severity: Problem
 Keywords: |
----------------------------------------+----------------------------
 Please note that this ticket is similar to Ticket#2936.

 When using named-pipes in message mode on Windows it is possible that the
 read operation on the client side will fail with GetLastError() ==
 ERROR_MORE_DATA. In the overlapped IO case the latter means that
 GetOverlappedResult(...) fails and reports this error.

 Now looking at the win_iocp_handle_service::do_read(...) when in the above
 scenario if the GetOverlappedResult(...) fails do_read(...) would update
 the ec parameter with the error value (in this case ERROR_MORE_DATA) and
 then boost::asio::windows::stream_handle::read_some(...) would throw. The
 latter may be incorrect as the ReadFile(...) function may have actually
 read some data but the information about this data (bytes read) would be
 lost when the exception is thrown leaving the upper layers practically
 unable to recover from this situation even if they'd catch the
 exception... (see attached code)

 It seems the fix for this should be to avoid throwing the exception by
 adding an "if" statement similar to the one after the ReadFile(...) call
 (several lines above in do_read(...)) e.g. making the code around
 GetOverlappedResult(...) look as follows:

   // Wait for the operation to complete.
   DWORD bytes_transferred = 0;
   ok = ::GetOverlappedResult(impl.handle_,
       &overlapped, &bytes_transferred, TRUE);
   if (!ok)
   {
     DWORD last_error = ::GetLastError();
     if (last_error != ERROR_MORE_DATA) // <---- added "if" statement
     {
       if (last_error == ERROR_HANDLE_EOF)
       {
         ec = boost::asio::error::eof;
       }
       else
       {
         ec = boost::system::error_code(last_error,
              boost::asio::error::get_system_category());
       }
       return 0;
     }
   }

 Please comment if the proposed fix is correct as I'd like to apply it
 before it is released in an official BOOST release.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8722>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:13 UTC