[Boost-bugs] [Boost C++ Libraries] #10174: call_stack not working when building asio as shared module on windows

Subject: [Boost-bugs] [Boost C++ Libraries] #10174: call_stack not working when building asio as shared module on windows
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-07-02 23:57:38


#10174: call_stack not working when building asio as shared module on windows
------------------------------+----------------------------
 Reporter: wberrier@… | Owner: chris_kohlhoff
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
  Version: Boost 1.55.0 | Severity: Problem
 Keywords: windows dispatch |
------------------------------+----------------------------
 The call_stack is not working when building asio as shared module on
 windows.

 Also, the call_stack doesn't work on windows when using asio as header
 only and loading a dll at runtime (ie: LoadLibrary) which is also using
 asio as header only.

 See and run the attached test case that demonstrates the problem in the
 following scenario:

 * MSVC 2010 Express SP1 32bit (I'm guessing it's an issue on other
 compilers as well, but this is what I was using)
 * build asio as a shared library according to instructions for "separate
 compilation" [ 1 ]
 * build and run the test case, where all cases should say "PASS"

 Now, I know the documentation says that .dispatch() *may* execute the
 handler right away (see discussion[ 2 ] on mailing list), so it's
 officially not a bug.

 BUT, I noticed that "strand.running_in_this_thread()" worked. That's what
 clued me in that call_stack was working as expected for
 running_in_this_thread(), but not for dispatch().

 It appears that the issue is with static storage for
 boost::asio::detail::callstack::top_ .

 It appears that two copies of this static storage item are being
 referenced: one from the .exe file, and one from the .dll (both of which
 include the asio headers).

 It looks like the reason "running_in_this_thread()" works is because it
 calls callstack<>::contains() from an .ipp file, which is included in the
 .dll so it references top_ from the .dll.

 In the case of using asio as header only, not running any asio code from a
 .dll, the issue is non-existent. There is no confusion as to which top_
 variable to use.

 See the attached patch to asio/detail/impl/strand_service.hpp that fixes
 strand.dispatch() by calling "running_in_this_thread()". That forces the
 reference of top_ from the .dll instead of the reference from the .exe
 that's linked against the asio dll or another .dll that includes asio
 headers.

 Possible fixes for this:
 1. put the definition of top_ in an .ipp file to include in the boost asio
 .dll so there's only one symbol for it.
 2. put all usages of call_stack in .ipp files (similar to the attached
 patch) so there's no confusion about the symbol (ugly and error prone,
 since it would have to be done for all use cases)

 It should be noted that in order for call_stack to work across a dll
 boundary (ie: sharing io_service or strand between a .exe and .dll), asio
 *must* be built as a shared library.

 Also, note that this only happens on Windows. Doing the equivalent with
 .so files works in Linux (maybe by chance? not sure...).

 Not having this fix makes .dispatch() pretty much useless when using asio
 on windows with .dlls.

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/10174>
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-02-16 18:50:16 UTC