I can't figure this out. I've tried everything. I have a socket class based on boost::asio, which seems to work fine until I add timeouts. For some reason io_service is calling the callbacks twice. The timeout is set for 90 seconds but it fires almost immediately. Has anyone here experienced such an issue?
For the record I'm not using any threads or workers or anything, but asio is using a few. I checked the thread id's and they are the same for all the output though (main thread).
Attempting to connect to 76.74.255.245:80 // initial function only called once
<ClientSocket::Connect> (76.74.255.245:80)
<ClientSocket::OnResolveComplete> (76.74.255.245:80)
<ClientSocket::OnResolveComplete> (76.74.255.245:80) // wth why twice?
Operation Cancelled: The I/O operation has been aborted because of either a thread exit or an application request // wth timeout is 90 seconds
<ClientSocket::Close> Closing socket normally. // great
<ClientSocket::OnConnectComplete> (76.74.255.245:80) // one of the resolvecomplete's must have started this
Operation Aborted: The I/O operation has been aborted because of either a thread exit or an application request // okay
<ClientSocket::Close> Closing socket normally. // okay
<ClientSocket::OnConnectComplete> (76.74.255.245:80) // again? why again? wth
Operation Aborted: The I/O operation has been aborted because of either a thread exit or an application request // right....................
<ClientSocket::Close> Closing socket normally. // gg
I tried everything. I tried using io_service::wrap around bind as the argument for deadline_timer, but no. Since deadline_timer is constructed with io_service as the argument, you'd assume it wouldn't require some special treatment I'm missing. I eventually figured maybe it's not clearing it's internal array of callbacks, so I destroyed deadline_timer each callback, but no luck.
Code:
public: ClientSocket(boost::asio::io_service& io_service) : service(io_service), socket(io_service), resolver(io_service), timer(io_service), timeout(90)
Code:
public: void Connect(std::string const& host, std::string const& type)
{
if(DEBUG_MESSAGES)
std::cout << "<ClientSocket::Connect> (" << host << ":" <<type << ")" << std::endl;
boost::asio::ip::tcp::resolver::query query(host, type);
if(this->timeout > 0)
{
this->timer.expires_from_now(boost::posix_time::seconds(this->timeout));
this->timer.async_wait(boost::bind(&ClientSocket::OnResolveComplete, shared_from_this(), boost::asio::placeholders::error, boost::asio::ip::tcp::resolver::iterator()));
}
this->resolver.async_resolve(query, boost::bind(&ClientSocket::OnResolveComplete, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::iterator));
}
Code:
private: boost::asio::deadline_timer timer;
boost::asio::ip::tcp::resolver resolver;
boost::asio::ip::tcp::socket socket;
boost::asio::streambuf data;
boost::asio::streambuf response;
boost::asio::streambuf request;
boost::asio::streambuf headers;
boost::asio::io_service& service;
OnResolveComplete immediately calls this->timer.cancel(); I tried io_service:: post (other thread suggestion) event though its in the same thread anyway, no luck.
Any help appreciated!!