Opened 5 years ago
#13329 new Bugs
BOOST_ASIO_ENABLE_CANCELIO must be globally defined
Reported by: | Owned by: | chris_kohlhoff | |
---|---|---|---|
Milestone: | To Be Determined | Component: | asio |
Version: | Boost 1.63.0 | Severity: | Problem |
Keywords: | Cc: |
Description
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():
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:
#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.