Boost C++ Libraries: Ticket #13329: BOOST_ASIO_ENABLE_CANCELIO must be globally defined https://svn.boost.org/trac10/ticket/13329 <p> Today I spent several hours debugging a problem, that was caused by <code>#define BOOST_ASIO_ENABLE_CANCELIO</code> </p> <p> I added this #define only in those source files, where I had compiler warnings about cancel() failing on windows XP. </p> <p> This resulted in async_connect() failing. </p> <p> The problem was in boost::Casio::Detail::win_iocp_socket_service::async_accept(): </p> <div class="wiki-code"><div class="code"><pre> <span class="n">start_accept_op</span><span class="p">(</span><span class="n">impl</span><span class="p">,</span> <span class="n">peer</span><span class="p">.</span><span class="n">is_open</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">new_socket</span><span class="p">(),</span> <span class="n">impl</span><span class="p">.</span><span class="n">protocol_</span><span class="p">.</span><span class="n">family</span><span class="p">(),</span> <span class="n">impl</span><span class="p">.</span><span class="n">protocol_</span><span class="p">.</span><span class="n">type</span><span class="p">(),</span> <span class="n">impl</span><span class="p">.</span><span class="n">protocol_</span><span class="p">.</span><span class="n">protocol</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">output_buffer</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">p</span><span class="o">-&gt;</span><span class="n">address_length</span><span class="p">(),</span> <span class="n">p</span><span class="p">.</span><span class="n">p</span><span class="p">);</span> </pre></div></div><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. </p> <p> I found out, that in impl.protocol_.family(), the member family_ had a different address, then in the calling method async_accept(). </p> <p> This seems to be caused by the following code in boost::asio::detail::win_iocp_socket_service_base: </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#if defined(BOOST_ASIO_ENABLE_CANCELIO)</span> <span class="c1">// The ID of the thread from which it is safe to cancel asynchronous</span> <span class="c1">// operations. 0 means no asynchronous operations have been started yet.</span> <span class="c1">// ~0 means asynchronous operations have been started from more than one</span> <span class="c1">// thread, and cancellation is not supported for the socket.</span> <span class="n">DWORD</span> <span class="n">safe_cancellation_thread_id_</span><span class="p">;</span> <span class="cp">#endif </span><span class="c1">// defined(BOOST_ASIO_ENABLE_CANCELIO)</span> </pre></div></div><p> 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. </p> <p> This only works, if BOOST_ASIO_ENABLE_CANCELIO is either defined or not in <strong>all</strong> sources, #include'ing boost/asio.hpp. </p> <p> 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. </p> <p> I was not able to find any hint about this fact in the documentation of boost asio. </p> <p> 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. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13329 Trac 1.4.3