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