diff --git a/ChangeLog b/ChangeLog index 023c878be..e76e5bf21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -76,6 +76,7 @@ release 0.14.5 * fixed rare piece-picker bug * fixed bug where one allowed-fast message would be sent even when disabled + * fixed race condition in UPnP which could lead to crash release 0.14.4 diff --git a/src/http_connection.cpp b/src/http_connection.cpp index 8b898fdee..f026974d9 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -65,6 +65,10 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri int default_port = protocol == "https" ? 443 : 80; + // keep ourselves alive even if the callback function + // deletes this object + boost::shared_ptr me(shared_from_this()); + if (protocol != "http" #ifdef TORRENT_USE_OPENSSL && protocol != "https" @@ -156,6 +160,10 @@ void http_connection::start(std::string const& hostname, std::string const& port m_read_pos = 0; m_priority = prio; + // keep ourselves alive even if the callback function + // deletes this object + boost::shared_ptr me(shared_from_this()); + if (ec) { m_resolver.get_io_service().post(boost::bind(&http_connection::callback @@ -222,6 +230,10 @@ void http_connection::on_connect_timeout() if (m_connection_ticket > -1) m_cc.done(m_connection_ticket); m_connection_ticket = -1; + // keep ourselves alive even if the callback function + // deletes this object + boost::shared_ptr me(shared_from_this()); + if (!m_endpoints.empty()) { error_code ec; @@ -283,6 +295,8 @@ void http_connection::on_resolve(error_code const& e { if (e) { + boost::shared_ptr me(shared_from_this()); + callback(e); close(); return; @@ -357,6 +371,7 @@ void http_connection::on_connect(error_code const& e) } else { + boost::shared_ptr me(shared_from_this()); callback(e); close(); } @@ -393,6 +408,7 @@ void http_connection::on_write(error_code const& e) { if (e) { + boost::shared_ptr me(shared_from_this()); callback(e); close(); return; @@ -427,6 +443,10 @@ void http_connection::on_read(error_code const& e TORRENT_ASSERT(m_download_quota >= 0); } + // keep ourselves alive even if the callback function + // deletes this object + boost::shared_ptr me(shared_from_this()); + // when using the asio SSL wrapper, it seems like // we get the shut_down error instead of EOF if (e == asio::error::eof || e == asio::error::shut_down) @@ -566,7 +586,7 @@ void http_connection::on_read(error_code const& e m_sock.async_read_some(asio::buffer(&m_recvbuffer[0] + m_read_pos , amount_to_read) , bind(&http_connection::on_read - , shared_from_this(), _1, _2)); + , me, _1, _2)); } void http_connection::on_assign_bandwidth(error_code const& e)