Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r60689 - in trunk: boost/asio/detail libs/asio/test/ip
From: chris_at_[hidden]
Date: 2010-03-18 07:08:20


Author: chris_kohlhoff
Date: 2010-03-18 07:08:19 EDT (Thu, 18 Mar 2010)
New Revision: 60689
URL: http://svn.boost.org/trac/boost/changeset/60689

Log:
Fix bug where 0-byte reads were incorrectly passing an eof error_code to the handler. Refs #4023.

Text files modified:
   trunk/boost/asio/detail/win_iocp_socket_service.hpp | 2
   trunk/libs/asio/test/ip/tcp.cpp | 144 ++++++++++++++++++++++++++++++++++++++++
   2 files changed, 146 insertions(+), 0 deletions(-)

Modified: trunk/boost/asio/detail/win_iocp_socket_service.hpp
==============================================================================
--- trunk/boost/asio/detail/win_iocp_socket_service.hpp (original)
+++ trunk/boost/asio/detail/win_iocp_socket_service.hpp 2010-03-18 07:08:19 EDT (Thu, 18 Mar 2010)
@@ -1059,6 +1059,8 @@
         // Check for connection closed.
         else if (!ec && bytes_transferred == 0
             && o->protocol_type_ == SOCK_STREAM
+ && !buffer_sequence_adapter<boost::asio::mutable_buffer,
+ MutableBufferSequence>::all_empty(o->buffers_)
             && !boost::is_same<MutableBufferSequence, null_buffers>::value)
         {
           ec = boost::asio::error::eof;

Modified: trunk/libs/asio/test/ip/tcp.cpp
==============================================================================
--- trunk/libs/asio/test/ip/tcp.cpp (original)
+++ trunk/libs/asio/test/ip/tcp.cpp 2010-03-18 07:08:19 EDT (Thu, 18 Mar 2010)
@@ -19,6 +19,9 @@
 #include <boost/bind.hpp>
 #include <cstring>
 #include <boost/asio/io_service.hpp>
+#include <boost/asio/placeholders.hpp>
+#include <boost/asio/read.hpp>
+#include <boost/asio/write.hpp>
 #include "../unit_test.hpp"
 #include "../archetypes/io_control_command.hpp"
 
@@ -300,6 +303,146 @@
 
 //------------------------------------------------------------------------------
 
+// ip_tcp_socket_runtime test
+// ~~~~~~~~~~~~~~~~~~~~~~~~~~
+// The following test checks the runtime operation of the ip::tcp::socket class.
+
+namespace ip_tcp_socket_runtime {
+
+static const char write_data[]
+ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+void handle_read_noop(const boost::system::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(!err);
+ BOOST_CHECK(bytes_transferred == 0);
+}
+
+void handle_write_noop(const boost::system::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(!err);
+ BOOST_CHECK(bytes_transferred == 0);
+}
+
+void handle_read(const boost::system::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(!err);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+}
+
+void handle_write(const boost::system::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(!err);
+ BOOST_CHECK(bytes_transferred == sizeof(write_data));
+}
+
+void handle_read_eof(const boost::system::error_code& err,
+ size_t bytes_transferred, bool* called)
+{
+ *called = true;
+ BOOST_CHECK(err == boost::asio::error::eof);
+ BOOST_CHECK(bytes_transferred == 0);
+}
+
+void test()
+{
+ using namespace std; // For memcmp.
+ using namespace boost::asio;
+ namespace ip = boost::asio::ip;
+
+ io_service ios;
+
+ ip::tcp::acceptor acceptor(ios, ip::tcp::endpoint(ip::tcp::v4(), 0));
+ ip::tcp::endpoint server_endpoint = acceptor.local_endpoint();
+ server_endpoint.address(ip::address_v4::loopback());
+
+ ip::tcp::socket client_side_socket(ios);
+ ip::tcp::socket server_side_socket(ios);
+
+ client_side_socket.connect(server_endpoint);
+ acceptor.accept(server_side_socket);
+
+ // No-op read.
+
+ bool read_noop_completed = false;
+ client_side_socket.async_read_some(
+ boost::asio::mutable_buffers_1(0, 0),
+ boost::bind(handle_read_noop,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ &read_noop_completed));
+
+ ios.run();
+ BOOST_CHECK(read_noop_completed);
+
+ // No-op write.
+
+ bool write_noop_completed = false;
+ client_side_socket.async_write_some(
+ boost::asio::const_buffers_1(0, 0),
+ boost::bind(handle_write_noop,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ &write_noop_completed));
+
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(write_noop_completed);
+
+ // Read and write to transfer data.
+
+ char read_buffer[sizeof(write_data)];
+ bool read_completed = false;
+ boost::asio::async_read(client_side_socket,
+ boost::asio::buffer(read_buffer),
+ boost::bind(handle_read,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ &read_completed));
+
+ bool write_completed = false;
+ boost::asio::async_write(server_side_socket,
+ boost::asio::buffer(write_data),
+ boost::bind(handle_write,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ &write_completed));
+
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(read_completed);
+ BOOST_CHECK(write_completed);
+ BOOST_CHECK(memcmp(read_buffer, write_data, sizeof(write_data)) == 0);
+
+ // A read when the peer closes socket should fail with eof.
+
+ bool read_eof_completed = false;
+ boost::asio::async_read(client_side_socket,
+ boost::asio::buffer(read_buffer),
+ boost::bind(handle_read_eof,
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred,
+ &read_eof_completed));
+
+ server_side_socket.close();
+
+ ios.reset();
+ ios.run();
+ BOOST_CHECK(read_eof_completed);
+}
+
+} // namespace ip_tcp_socket_runtime
+
+//------------------------------------------------------------------------------
+
 // ip_tcp_acceptor_runtime test
 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // The following test checks the runtime operation of the ip::tcp::acceptor
@@ -383,6 +526,7 @@
   test->add(BOOST_TEST_CASE(&ip_tcp_compile::test));
   test->add(BOOST_TEST_CASE(&ip_tcp_runtime::test));
   test->add(BOOST_TEST_CASE(&ip_tcp_socket_compile::test));
+ test->add(BOOST_TEST_CASE(&ip_tcp_socket_runtime::test));
   test->add(BOOST_TEST_CASE(&ip_tcp_acceptor_runtime::test));
   return test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk