[Boost-bugs] [Boost C++ Libraries] #9203: asio::strand allocation algorithm causes handlers to execute on the wrong strand.

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