Subject: [Boost-bugs] [Boost C++ Libraries] #9203: asio::strand allocation algorithm causes handlers to execute on the wrong strand.
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-10-07 02:43:43
#9203: asio::strand allocation algorithm causes handlers to execute on the wrong
strand.
------------------------------------------+----------------------------
Reporter: Greg Barron <gregbarron71@â¦> | Owner: chris_kohlhoff
Type: Bugs | Status: new
Milestone: To Be Determined | Component: asio
Version: Boost 1.54.0 | Severity: Problem
Keywords: |
------------------------------------------+----------------------------
Hi.
We recently updated from boost::asio::1.41 to boost::asio::1.53. We
immediately noticed several unittests failing with socket write timeouts
and initially didn't think too much of it. However after further
investigation we believe that the strand implementation allocation
algorithm in strand_service.ipp is the cause of these issues.
The allocation algorithm is causing deadlocks/starvation because
strand_service::construct can and does provide a
strand_service::implementation_type which is currently in use by another
io_service::strand.
This results in handlers wrapped on io_service::strand-a being executed on
io_service::strand-b. If the previous handler executing on
io_service::strand-b blocks or delays the handler which should be running
on io_service::strand-a will be delayed or never execute.
I have attached a sample which will demonstrate this issue:
* Modify stand.hpp to make the members public (for debug printing).
* Compile as 'g++ -g main.cpp -lboost_thread -lpthread -lboost_system'.
* The example should run forever printing from the 'printer' and
'blocker'. After a little time the 'printer' will stop printing because
the condition has been reached.
I have tested that it demonstrates the issue correctly in ubuntu
10.04/13.04 as well as on an ARM target (Linux (none) 2.6.35.3-dt.0.55121+
#1 Mon Dec 17 12:06:28 EST 2012 armv5tejl GNU/Linux).
The issue occurs with any version of boost from 1.42 (including
trunk_at_86189).
This is not just a unittest issue for us. We have a TCP server accepting
connections and performing async_reads/async_writes on the connection. In
the same process we have another thread creating connections to the server
and sending/receiving using blocking reads/writes with raw sockets (auto
generated code by gSoap). Both the client and server side use strands to
sequence their relative operations. Frequently the stand belonging to the
connection handler on the server side is given the same implementation of
the strand owned by the client side. Deadlock ensues until the client
times out (20 seconds).
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/9203> 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:14 UTC