Subject: [Boost-bugs] [Boost C++ Libraries] #3670: endless loop in dev_poll_reactor on Solaris
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-11-25 09:53:55
#3670: endless loop in dev_poll_reactor on Solaris
------------------------------------+---------------------------------------
Reporter: dirkmoermans@⦠| Owner: chris_kohlhoff
Type: Bugs | Status: new
Milestone: Boost 1.42.0 | Component: asio
Version: Boost 1.41.0 | Severity: Regression
Keywords: |
------------------------------------+---------------------------------------
The following example-program exposes high CPU-usage on Solaris 10,
despite not doing anything useful while sleeping. Top reports a CPU-usage
between 10 and 25% on a 4 CPU-box.
In order to reproduce, a TCP-server has to be listening on the configured
host-port.
{{{
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <time.h>
#include <vector>
#include <iostream>
// g++ -pthread -g2 -I/opt/include/boost-1_41 -L/opt/lib -lboost_system-
gcc43-mt-1_41 -lboost_thread-gcc43-mt-1_41 -lsocket -lnsl f.cc
// this program exposes a high CPU usage when run on solaris 10 using the
dev_poll_reactor (the default).
const char HOSTNAME[]="localhost";
const char PORT[]="46000";
const int THREADS=3;
const int SOCKETS=10;
const int LOOPS=10;
const int SLEEPTIME=10; // seconds
void handler(const boost::system::error_code& error)
{
std::cout << "socket connected '" << error << "'" << std::endl;
}
int main()
{
using namespace boost::asio::ip;
boost::asio::io_service service;
boost::asio::io_service::work work(service);
boost::thread_group pool;
for(int i=0;i<THREADS;++i)
pool.create_thread(boost::bind(&boost::asio::io_service::run,
boost::ref(service)));
tcp::resolver resolver(service);
tcp::resolver::query query(HOSTNAME,PORT);
tcp::resolver::iterator result=resolver.resolve(query);
const tcp::resolver::iterator end;
if(result==end)
{
return -1;
}
for(int i=0;0<LOOPS;++i)
{
typedef std::vector<boost::shared_ptr<boost::asio::ip::tcp::socket>
> Sockets;
Sockets sockets;
for(int j=0;j<SOCKETS;++j)
{
sockets.push_back(
boost::shared_ptr<boost::asio::ip::tcp::socket>
(new
boost::asio::ip::tcp::socket(service,boost::asio::ip::tcp::v4())));
}
for(Sockets::iterator si=sockets.begin();
si!=sockets.end();
++si)
{
(*si)->async_connect(*result,handler);
}
sleep(SLEEPTIME);
}
}
}}}
The cause seems to be an endless loop in dev_poll_reactor::run
The problematic stacktrace:
{{{
#0 0xffffffff7e0d3a50 in _write () from /lib/64/libc.so.1
#1 0xffffffff7e0c4394 in write () from /lib/64/libc.so.1
#2 0x0000000100024258 in
boost::asio::detail::dev_poll_reactor<false>::run (this=0x100131e80,
block=true) at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/asio/detail/dev_poll_reactor.hpp:467
#3 0x0000000100024850 in
boost::asio::detail::task_io_service<boost::asio::detail::dev_poll_reactor<false>
>::do_one (this=0x10012f090, lock=@0xffffffff7d0fba28,
this_idle_thread=0xffffffff7d0fba08, ec=@0xffffffff7d0fbb18)
at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/asio/detail/task_io_service.hpp:260
#4 0x0000000100024adc in
boost::asio::detail::task_io_service<boost::asio::detail::dev_poll_reactor<false>
>::run (this=0x10012f090, ec=@0xffffffff7d0fbb18)
at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/asio/detail/task_io_service.hpp:103
#5 0x0000000100024c34 in boost::asio::io_service::run
(this=0xffffffff7ffff028) at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/asio/impl/io_service.ipp:58
#6 0x000000010000d33c in boost::_mfi::mf0<unsigned long,
boost::asio::io_service>::operator() (this=0x100131b20,
t=@0xffffffff7ffff028) at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/bind/mem_fn_template.hpp:68
#7 0x000000010000d400 in
boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service>
>::operator()<unsigned long, boost::_mfi::mf0<unsigned long,
boost::asio::io_service>, boost::_bi::list0> (this=0x100131b30,
f=@0x100131b20, a=@0xffffffff7d0fbd9f) at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/bind/bind.hpp:236
#8 0x000000010000d460 in boost::_bi::bind_t<unsigned long,
boost::_mfi::mf0<unsigned long, boost::asio::io_service>,
boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> >
>::operator() (this=0x100131b20)
at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/bind/bind_template.hpp:20
#9 0x000000010000d48c in
boost::detail::thread_data<boost::_bi::bind_t<unsigned long,
boost::_mfi::mf0<unsigned long, boost::asio::io_service>,
boost::_bi::list1<boost::reference_wrapper<boost::asio::io_service> > >
>::run (
this=0x100131a50) at
/opt/gnu4u_prince_ext/include/boost-1_41/boost/thread/detail/thread.hpp:56
#10 0xffffffff7f00ba30 in thread_proxy () from /opt/gnu4u_prince_ext/lib
/libboost_thread-gcc43-mt-1_41.so.1.41.0
#11 0xffffffff7e0d24e0 in _lwp_start () from /lib/64/libc.so.1
#12 0xffffffff7e0d24e0 in _lwp_start () from /lib/64/libc.so.1
}}}
the local variables just after the write:
{{{
(gdb) info locals
ev = {fd = 13, events = 24, revents = 0}
result = 8
more_reads = false
more_writes = false
more_except = false
ec = {m_val = 0, m_cat = 0xffffffff7f4033a8}
descriptor = 13
i = 0
lock = {<boost::noncopyable_::noncopyable> = {<No data fields>}, mutex_ =
@0x100131ea8, locked_ = true}
events_size = 0
timeout = -1
events = {{fd = 13, events = 28, revents = 4}, {fd = 14, events = 28,
revents = 4}, {fd = 16, events = 28, revents = 4}, {fd = 0, events = 0,
revents = 0} <repeats 125 times>}
dp = {dp_fds = 0xffffffff7d0fb2d0, dp_nfds = 128, dp_timeout = -1}
num_events = 3
sb = {<boost::noncopyable_::noncopyable> = {<No data fields>}, blocked_ =
true, old_mask_ = {__sigbits = {0, 0, 0, 0}}}
}}}
The program works fine on Linux and works fine on Solaris when compiled
with the flag -DBOOST_ASIO_DISABLE_DEV_POLL.
I am pretty sure that this behaviour has been present since at least boost
1.37.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3670> 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:01 UTC