[Boost-bugs] [Boost C++ Libraries] #13329: BOOST_ASIO_ENABLE_CANCELIO must be globally defined

Subject: [Boost-bugs] [Boost C++ Libraries] #13329: BOOST_ASIO_ENABLE_CANCELIO must be globally defined
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-12-06 19:23:40


#13329: BOOST_ASIO_ENABLE_CANCELIO must be globally defined
-------------------------------------+----------------------------
 Reporter: Mario Klebsch <mario@…> | Owner: chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost 1.63.0 | Severity: Problem
 Keywords: |
-------------------------------------+----------------------------
 Today I spent several hours debugging a problem, that was caused by
 `#define BOOST_ASIO_ENABLE_CANCELIO`

 I added this #define only in those source files, where I had compiler
 warnings about cancel() failing on windows XP.

 This resulted in async_connect() failing.

 The problem was in
 boost::Casio::Detail::win_iocp_socket_service::async_accept():

 {{{
 #!C++
     start_accept_op(impl, peer.is_open(), p.p->new_socket(),
         impl.protocol_.family(), impl.protocol_.type(),
         impl.protocol_.protocol(), p.p->output_buffer(),
         p.p->address_length(), p.p);
 }}}

 When I inspected the value if impl.protocol_.family_, the correct value
 was shown in the debugger.
 But when I stepped into impl.protocol_.family(), an incorrect value was
 shown.

 I found out, that in impl.protocol_.family(), the member family_ had a
 different address, then in the calling method async_accept().

 This seems to be caused by the following code in
 boost::asio::detail::win_iocp_socket_service_base:

 {{{
 #!C++
 #if defined(BOOST_ASIO_ENABLE_CANCELIO)
     // The ID of the thread from which it is safe to cancel asynchronous
     // operations. 0 means no asynchronous operations have been started
 yet.
     // ~0 means asynchronous operations have been started from more than
 one
     // thread, and cancellation is not supported for the socket.
     DWORD safe_cancellation_thread_id_;
 #endif // defined(BOOST_ASIO_ENABLE_CANCELIO)
 }}}

 This makes the size of this class (and therefore the offsets of all member
 variables of derived classes depend on wether BOOST_ASIO_ENABLE_CANCELIO
 is defined or not.

 This only works, if BOOST_ASIO_ENABLE_CANCELIO is either defined or not in
 **all** sources, #include'ing boost/asio.hpp.

 If it is only #define'ed in those source files, where the compiler emits
 the warning about cancel() failing on windows XP, this problem may occur.

 I was not able to find any hint about this fact in the documentation of
 boost asio.

 I would just unconditionally declare the member variable
 safe_cancellation_thread_id_. I am no sure, whether this might trigger
 compiler warnings about an unused or uninitialized variable, but it should
 be possible to suppress these warnings.

-- 
Ticket URL: <https://svn.boost.org/trac10/boost/ticket/13329>
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-12-06 19:30:48 UTC