[Boost-bugs] [Boost C++ Libraries] #8967: Spurious zero bytes written and eof notifications highlight ASIO IOCP issues

Subject: [Boost-bugs] [Boost C++ Libraries] #8967: Spurious zero bytes written and eof notifications highlight ASIO IOCP issues
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-08-05 16:11:43


#8967: Spurious zero bytes written and eof notifications highlight ASIO IOCP
issues
-------------------------------------------------+-------------------------
 Reporter: simoncperkins@… | Owner:
     Type: Bugs | chris_kohlhoff
Milestone: To Be Determined | Status: new
  Version: Boost 1.54.0 | Component: asio
 Keywords: eof GetQueuedCompletionStatus | Severity: Problem
  WSARecv WSASend overlapped |
-------------------------------------------------+-------------------------
 I have been working on a multi-threaded boost asio based HTTP client. My
 tests perform hundreds of HTTP calls against a variety of web servers.

 The tests run reliably on OS X and on Windows with the
 BOOST_ASIO_DISABLE_IOCP flag set. I use multiple threads calling
 io_service:run().

 However, on Windows using IOCP I was seeing occasional notifications that
 zero bytes had been written with async_write even though data had
 successfully been written to the socket and was received by the web
 server.

 I also saw random boost::asio::error::eof notications from async_read_some
 even though there was more data to read and the tcp socket's available()
 method returned a non-zero value.

 In trying to track down the problem I reviewed the implementation of the
 ASIO IOCP implementation and found several issues:

  1) WSARecv and WSASend were supplying non-NULL for the
 lpNumberOfBytesRecvd parameter with an overlapped socket. The MSDN docs
 say "Use NULL for this parameter if the lpOverlapped parameter is not NULL
 to avoid potentially erroneous results. This parameter can be NULL only if
 the lpOverlapped parameter is not NULL.

  2) PostQueuedCompletionStatus is only needed to deliver errors where
 WSARecv and WSASend synchronously fail. Instead it was always being used
 for successful synchronous and pending I/O through
 win_iocp_io_service::on_pending. This is not required because an
 overlapped socket's results are automatically delivered to thread(s)
 calling GetQueuedCompletionStatus. I believe this could lead to incorrect
 behaviour due to the explicit and implicit posting of each I/O request.
 Also, this would increase the number of notifications that the IOCP would
 have to handle.

  3) The ready_ flag seems to be unnecessary for a correct implementation
 and could cause notifications from QueuedCompletionStatus to be ignored

 I have attached a patch file of my changes with comments prefixed with SP:
 indicating the reason for each of the changes.

 After applying these changes to Boost ASIO in 1.54 I can now reliably run
 the IOCP version of the tests on Windows 7.

 I believe the modified implementation is closer to that expected when
 using sockets and I/O completion ports.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8967>
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