Boost logo

Boost Users :

Subject: Re: [Boost-users] [Asio] deadline_timer doesn't fire in some cases
From: Igor R (boost.lists_at_[hidden])
Date: 2014-05-23 11:15:15


> We have a client application that uses deadline_timers in order to implement timeouts for read and write operations on a socket. We have an io_service thread that runs boost::asio::io_service::run.
> The _ioService is used by resolver, by read, write, connect timers (implemented using deadline_timer) and also by tcp::socket. On socket we are using only synchronous operations like:
> connect, read_some, write_some. The socket is blocking. Also for resolver we are using the synchronous operation resolve.
> Our problem is that although read timer is set to 100 milliseconds, it doesn't fire up and the application is blocked in read_some function for like 15 minutes. In onReadTimeout callback we are closing the socket. I can reproduce this behavior every time by changing the connection settings on the virtual machine that host the server to a dummy interface.
> Currently I sow this behavior in logs and i did a core dump of the client process using gcore and sow the stack trace on all threads.
>
> I added also the stack trace. The thread that is blocked for 15 minutes is thread 18. This thread contain in stack trace boost::asio::io_service::run. Also thread 9 and thread 10 contains boost::asio::io_service::run.
>
> Thread 18 calls
> _readTimer.expires_from_now(boost::posix_time::milliseconds(_readTimeout), ec);
> _readTimer.async_wait(boost::bind(&BlockingTcpClient::onReadTimeout, this, boost::asio::placeholders::error));
> with readTimeout set to 100 and then _pSocket->write_some. In BlockingTcpClient::onReadTimeout we are closing the socket. So read_some should be blocked for maximum 100 miliseconds.
>
> Maybe the problem is that the read timer uses the same io_service that currently is blocked in read_some.

Yes, if you block a completion handler that io_service invoked (and it
look like that's what you do), then other completion handlers pending
on the same io_service/thread won't be invoked.
You could slightly change the design to avoid such a situation: just
run a dedicated io_service in a separate thread, and post() there any
"heavy" operation.


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net