fix http_connection timeout (improves shutdown delay)

This commit is contained in:
Arvid Norberg 2012-01-21 08:18:41 +00:00
parent a77342b9a4
commit 5c8d476022
2 changed files with 23 additions and 10 deletions

View File

@ -148,8 +148,10 @@ private:
http_connect_handler m_connect_handler; http_connect_handler m_connect_handler;
http_filter_handler m_filter_handler; http_filter_handler m_filter_handler;
deadline_timer m_timer; deadline_timer m_timer;
time_duration m_timeout; time_duration m_read_timeout;
time_duration m_completion_timeout;
ptime m_last_receive; ptime m_last_receive;
ptime m_start_time;
// bottled means that the handler is called once, when // bottled means that the handler is called once, when
// everything is received (and buffered in memory). // everything is received (and buffered in memory).
// non bottled means that once the headers have been // non bottled means that once the headers have been

View File

@ -69,6 +69,7 @@ http_connection::http_connection(io_service& ios, connection_queue& cc
, m_filter_handler(fh) , m_filter_handler(fh)
, m_timer(ios) , m_timer(ios)
, m_last_receive(time_now()) , m_last_receive(time_now())
, m_start_time(time_now())
, m_bottled(bottled) , m_bottled(bottled)
, m_called(false) , m_called(false)
#ifdef TORRENT_USE_OPENSSL #ifdef TORRENT_USE_OPENSSL
@ -221,9 +222,10 @@ void http_connection::start(std::string const& hostname, std::string const& port
// deletes this object // deletes this object
boost::shared_ptr<http_connection> me(shared_from_this()); boost::shared_ptr<http_connection> me(shared_from_this());
m_timeout = timeout; m_completion_timeout = timeout;
m_read_timeout = (std::max)(seconds(5), timeout / 5);
error_code ec; error_code ec;
m_timer.expires_from_now(m_timeout, ec); m_timer.expires_from_now(m_completion_timeout, ec);
#if defined TORRENT_ASIO_DEBUGGING #if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("http_connection::on_timeout"); add_outstanding_async("http_connection::on_timeout");
#endif #endif
@ -269,7 +271,8 @@ void http_connection::start(std::string const& hostname, std::string const& port
m_i2p_conn = i2p_conn; m_i2p_conn = i2p_conn;
// quadruple the timeout for i2p destinations // quadruple the timeout for i2p destinations
// because i2p is sloooooow // because i2p is sloooooow
m_timeout *= 4; m_completion_timeout *= 4;
m_read_timeout *= 4;
} }
#endif #endif
@ -400,7 +403,10 @@ void http_connection::on_timeout(boost::weak_ptr<http_connection> p
if (e == asio::error::operation_aborted) return; if (e == asio::error::operation_aborted) return;
if (c->m_last_receive + c->m_timeout < time_now_hires()) ptime now = time_now_hires();
if (c->m_start_time + c->m_completion_timeout < now
|| c->m_last_receive + c->m_read_timeout < now)
{ {
if (c->m_connection_ticket > -1 && !c->m_endpoints.empty()) if (c->m_connection_ticket > -1 && !c->m_endpoints.empty())
{ {
@ -409,7 +415,9 @@ void http_connection::on_timeout(boost::weak_ptr<http_connection> p
#endif #endif
error_code ec; error_code ec;
c->m_sock.close(ec); c->m_sock.close(ec);
c->m_timer.expires_at(c->m_last_receive + c->m_timeout, ec); c->m_timer.expires_at((std::min)(
c->m_last_receive + c->m_read_timeout
, c->m_start_time + c->m_completion_timeout), ec);
c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1)); c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1));
} }
else else
@ -425,7 +433,9 @@ void http_connection::on_timeout(boost::weak_ptr<http_connection> p
add_outstanding_async("http_connection::on_timeout"); add_outstanding_async("http_connection::on_timeout");
#endif #endif
error_code ec; error_code ec;
c->m_timer.expires_at(c->m_last_receive + c->m_timeout, ec); c->m_timer.expires_at((std::min)(
c->m_last_receive + c->m_read_timeout
, c->m_start_time + c->m_completion_timeout), ec);
c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1)); c->m_timer.async_wait(boost::bind(&http_connection::on_timeout, p, _1));
} }
@ -526,7 +536,7 @@ void http_connection::queue_connect()
m_cc.enqueue(boost::bind(&http_connection::connect, shared_from_this(), _1, target) m_cc.enqueue(boost::bind(&http_connection::connect, shared_from_this(), _1, target)
, boost::bind(&http_connection::on_connect_timeout, shared_from_this()) , boost::bind(&http_connection::on_connect_timeout, shared_from_this())
, m_timeout, m_priority); , m_read_timeout, m_priority);
} }
void http_connection::connect(int ticket, tcp::endpoint target_address) void http_connection::connect(int ticket, tcp::endpoint target_address)
@ -570,6 +580,7 @@ void http_connection::on_connect(error_code const& e)
} }
m_last_receive = time_now_hires(); m_last_receive = time_now_hires();
m_start_time = m_last_receive;
if (!e) if (!e)
{ {
if (m_connect_handler) m_connect_handler(*this); if (m_connect_handler) m_connect_handler(*this);
@ -773,7 +784,7 @@ void http_connection::on_read(error_code const& e
= parse_url_components(location, ec); = parse_url_components(location, ec);
if (!ec) if (!ec)
{ {
get(location, m_timeout, m_priority, &m_proxy, m_redirects - 1 get(location, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1
, m_user_agent, m_bind_addr , m_user_agent, m_bind_addr
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn , m_i2p_conn
@ -794,7 +805,7 @@ void http_connection::on_read(error_code const& e
url += '/'; url += '/';
url += location; url += location;
get(url, m_timeout, m_priority, &m_proxy, m_redirects - 1 get(url, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1
, m_user_agent, m_bind_addr , m_user_agent, m_bind_addr
#if TORRENT_USE_I2P #if TORRENT_USE_I2P
, m_i2p_conn , m_i2p_conn