forked from premiere/premiere-libtorrent
asio handlers are now properly cancelled when destructing the session object, race conditions are avoided by waiting for the io service to complete all tasks
This commit is contained in:
parent
fe5e88b548
commit
8f07edbed2
|
@ -375,12 +375,6 @@ namespace libtorrent
|
|||
// buffers from.
|
||||
boost::pool<> m_send_buffers;
|
||||
|
||||
// this is where all active sockets are stored.
|
||||
// the selector can sleep while there's no activity on
|
||||
// them
|
||||
io_service m_io_service;
|
||||
asio::strand m_strand;
|
||||
|
||||
// the file pool that all storages in this session's
|
||||
// torrents uses. It sets a limit on the number of
|
||||
// open files by this session.
|
||||
|
@ -395,6 +389,12 @@ namespace libtorrent
|
|||
// object.
|
||||
disk_io_thread m_disk_thread;
|
||||
|
||||
// this is where all active sockets are stored.
|
||||
// the selector can sleep while there's no activity on
|
||||
// them
|
||||
io_service m_io_service;
|
||||
asio::strand m_strand;
|
||||
|
||||
// this is a list of half-open tcp connections
|
||||
// (only outgoing connections)
|
||||
// this has to be one of the last
|
||||
|
@ -646,7 +646,7 @@ namespace libtorrent
|
|||
|
||||
void debug_log(const std::string& line)
|
||||
{
|
||||
(*m_ses.m_logger) << line << "\n";
|
||||
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
|
||||
}
|
||||
session_impl& m_ses;
|
||||
};
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
void done(int ticket);
|
||||
void limit(int limit);
|
||||
int limit() const;
|
||||
void close();
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
|
|
|
@ -130,6 +130,8 @@ namespace libtorrent
|
|||
, proxy_settings const& ps
|
||||
, std::string const& password = "");
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
boost::intrusive_ptr<http_tracker_connection> self()
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace libtorrent
|
|||
|
||||
void fail(int code, char const* msg);
|
||||
void fail_timeout();
|
||||
void close();
|
||||
virtual void close();
|
||||
address const& bind_interface() const { return m_bind_interface; }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -74,6 +74,8 @@ namespace libtorrent
|
|||
, boost::weak_ptr<request_callback> c
|
||||
, session_settings const& stn);
|
||||
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
enum action_t
|
||||
|
|
|
@ -86,6 +86,11 @@ namespace libtorrent
|
|||
try_connect();
|
||||
}
|
||||
|
||||
void connection_queue::close()
|
||||
{
|
||||
m_timer.cancel();
|
||||
}
|
||||
|
||||
void connection_queue::limit(int limit)
|
||||
{ m_half_open_limit = limit; }
|
||||
|
||||
|
|
|
@ -489,7 +489,9 @@ namespace libtorrent
|
|||
, boost::lexical_cast<std::string>(m_port));
|
||||
m_name_lookup.async_resolve(q, m_strand.wrap(
|
||||
boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2)));
|
||||
set_timeout(m_settings.tracker_completion_timeout
|
||||
set_timeout(req.event == tracker_request::stopped
|
||||
? m_settings.stop_tracker_timeout
|
||||
: m_settings.tracker_completion_timeout
|
||||
, m_settings.tracker_receive_timeout);
|
||||
}
|
||||
|
||||
|
@ -503,6 +505,17 @@ namespace libtorrent
|
|||
fail_timeout();
|
||||
}
|
||||
|
||||
void http_tracker_connection::close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
m_name_lookup.cancel();
|
||||
if (m_connection_ticket > -1) m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
m_timed_out = true;
|
||||
tracker_connection::close();
|
||||
}
|
||||
|
||||
void http_tracker_connection::name_lookup(asio::error_code const& error
|
||||
, tcp::resolver::iterator i) try
|
||||
{
|
||||
|
@ -759,7 +772,6 @@ namespace libtorrent
|
|||
if (m_parser.status_code() != 200)
|
||||
{
|
||||
fail(m_parser.status_code(), m_parser.message().c_str());
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -821,6 +833,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(false);
|
||||
}
|
||||
#endif
|
||||
close();
|
||||
}
|
||||
|
||||
peer_entry http_tracker_connection::extract_peer_info(const entry& info)
|
||||
|
|
|
@ -547,8 +547,8 @@ namespace detail
|
|||
, fingerprint const& cl_fprint
|
||||
, char const* listen_interface)
|
||||
: m_send_buffers(send_buffer_size)
|
||||
, m_strand(m_io_service)
|
||||
, m_files(40)
|
||||
, m_strand(m_io_service)
|
||||
, m_half_open(m_io_service)
|
||||
, m_download_channel(m_io_service, peer_connection::download_channel)
|
||||
, m_upload_channel(m_io_service, peer_connection::upload_channel)
|
||||
|
@ -675,6 +675,14 @@ namespace detail
|
|||
if (m_dht) m_dht->stop();
|
||||
#endif
|
||||
m_timer.cancel();
|
||||
|
||||
// close the listen sockets
|
||||
for (std::list<listen_socket_t>::iterator i = m_listen_sockets.begin()
|
||||
, end(m_listen_sockets.end()); i != end; ++i)
|
||||
{
|
||||
i->sock->close();
|
||||
}
|
||||
|
||||
// abort all torrents
|
||||
for (torrent_map::iterator i = m_torrents.begin()
|
||||
, end(m_torrents.end()); i != end; ++i)
|
||||
|
@ -682,7 +690,15 @@ namespace detail
|
|||
i->second->abort();
|
||||
}
|
||||
|
||||
m_io_service.stop();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " aborting all tracker requests\n";
|
||||
#endif
|
||||
m_tracker_manager.abort_all_requests();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " shutting down connection queue\n";
|
||||
#endif
|
||||
m_half_open.close();
|
||||
|
||||
mutex::scoped_lock l2(m_checker_impl.m_mutex);
|
||||
// abort the checker thread
|
||||
|
@ -1474,20 +1490,12 @@ namespace detail
|
|||
while (!m_abort);
|
||||
|
||||
deadline_timer tracker_timer(m_io_service);
|
||||
// this will remove the port mappings
|
||||
if (m_natpmp.get())
|
||||
m_natpmp->close();
|
||||
if (m_upnp.get())
|
||||
m_upnp->close();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " locking mutex\n";
|
||||
#endif
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " aborting all tracker requests\n";
|
||||
#endif
|
||||
m_tracker_manager.abort_all_requests();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " sending stopped to all torrent's trackers\n";
|
||||
|
@ -2127,16 +2135,10 @@ namespace detail
|
|||
|
||||
session_impl::~session_impl()
|
||||
{
|
||||
abort();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << "\n\n *** shutting down session *** \n\n";
|
||||
#endif
|
||||
// lock the main thread and abort it
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
m_abort = true;
|
||||
m_io_service.stop();
|
||||
l.unlock();
|
||||
abort();
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_logger) << time_now_string() << " waiting for main thread\n";
|
||||
|
|
|
@ -3055,7 +3055,7 @@ namespace libtorrent
|
|||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
void torrent::debug_log(const std::string& line)
|
||||
{
|
||||
(*m_ses.m_logger) << line << "\n";
|
||||
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -302,12 +302,12 @@ namespace libtorrent
|
|||
{
|
||||
m_completion_timeout = completion_timeout;
|
||||
m_read_timeout = read_timeout;
|
||||
m_start_time = time_now();
|
||||
m_read_time = time_now();
|
||||
m_start_time = m_read_time = time_now();
|
||||
|
||||
m_timeout.expires_at((std::min)(
|
||||
m_read_time + seconds(m_read_timeout)
|
||||
, m_start_time + seconds(m_completion_timeout)));
|
||||
, m_start_time + seconds((std::min)(m_completion_timeout
|
||||
, m_read_timeout))));
|
||||
m_timeout.async_wait(m_strand.wrap(bind(
|
||||
&timeout_handler::timeout_callback, self(), _1)));
|
||||
}
|
||||
|
@ -343,7 +343,8 @@ namespace libtorrent
|
|||
|
||||
m_timeout.expires_at((std::min)(
|
||||
m_read_time + seconds(m_read_timeout)
|
||||
, m_start_time + seconds(m_completion_timeout)));
|
||||
, m_start_time + seconds((std::min)(m_completion_timeout
|
||||
, m_read_timeout))));
|
||||
m_timeout.async_wait(m_strand.wrap(
|
||||
bind(&timeout_handler::timeout_callback, self(), _1)));
|
||||
}
|
||||
|
@ -570,9 +571,12 @@ namespace libtorrent
|
|||
for (tracker_connections_t::const_iterator i =
|
||||
m_connections.begin(); i != m_connections.end(); ++i)
|
||||
{
|
||||
if (!*i) continue;
|
||||
tracker_request const& req = (*i)->tracker_req();
|
||||
if (req.event == tracker_request::stopped)
|
||||
keep_connections.push_back(*i);
|
||||
else
|
||||
(*i)->close();
|
||||
}
|
||||
|
||||
std::swap(m_connections, keep_connections);
|
||||
|
|
|
@ -96,7 +96,9 @@ namespace libtorrent
|
|||
m_name_lookup.async_resolve(q
|
||||
, m_strand.wrap(boost::bind(
|
||||
&udp_tracker_connection::name_lookup, self(), _1, _2)));
|
||||
set_timeout(m_settings.tracker_completion_timeout
|
||||
set_timeout(req.event == tracker_request::stopped
|
||||
? m_settings.stop_tracker_timeout
|
||||
: m_settings.tracker_completion_timeout
|
||||
, m_settings.tracker_receive_timeout);
|
||||
}
|
||||
|
||||
|
@ -156,11 +158,20 @@ namespace libtorrent
|
|||
|
||||
void udp_tracker_connection::on_timeout()
|
||||
{
|
||||
m_socket.close();
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
m_name_lookup.cancel();
|
||||
fail_timeout();
|
||||
}
|
||||
|
||||
void udp_tracker_connection::close()
|
||||
{
|
||||
asio::error_code ec;
|
||||
m_socket.close(ec);
|
||||
m_name_lookup.cancel();
|
||||
tracker_connection::close();
|
||||
}
|
||||
|
||||
void udp_tracker_connection::send_udp_connect()
|
||||
{
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
|
@ -468,6 +479,7 @@ namespace libtorrent
|
|||
, complete, incomplete);
|
||||
|
||||
m_man.remove_request(this);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
@ -543,6 +555,7 @@ namespace libtorrent
|
|||
if (!cb)
|
||||
{
|
||||
m_man.remove_request(this);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -551,6 +564,7 @@ namespace libtorrent
|
|||
, complete, incomplete);
|
||||
|
||||
m_man.remove_request(this);
|
||||
close();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue