Opened 10 months ago

#13329 new Bugs

BOOST_ASIO_ENABLE_CANCELIO must be globally defined

Reported by: Mario Klebsch <mario@…> Owned by: chris_kohlhoff
Milestone: To Be Determined Component: asio
Version: Boost 1.63.0 Severity: Problem
Keywords: Cc:


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_.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, an incorrect value was shown.

I found out, that in, 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:

    // 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_;

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.

Change History (0)

Note: See TracTickets for help on using tickets.