more network thread asserts to make sure only the network thread touches network-thread only data. Also delay starting the network thread until after the session constructor is done with its setup

This commit is contained in:
Arvid Norberg 2010-12-04 22:20:31 +00:00
parent 94ef3eaf4b
commit 1c99bf1de3
4 changed files with 68 additions and 10 deletions

View File

@ -151,7 +151,8 @@ namespace libtorrent
#endif
);
~session_impl();
void start();
void init();
void start_session();
#ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(
@ -160,6 +161,7 @@ namespace libtorrent
#ifdef TORRENT_DEBUG
bool has_peer(peer_connection const* p) const
{
TORRENT_ASSERT(is_network_thread());
return std::find_if(m_connections.begin(), m_connections.end()
, boost::bind(&boost::intrusive_ptr<peer_connection>::get, _1) == p)
!= m_connections.end();
@ -184,11 +186,9 @@ namespace libtorrent
void incoming_connection(boost::shared_ptr<socket_type> const& s);
#ifdef TORRENT_DEBUG
#if defined BOOST_HAS_PTHREADS
pthread_t m_network_thread;
#endif
bool is_network_thread() const
{
if (m_network_thread == 0) return true;
#if defined BOOST_HAS_PTHREADS
return m_network_thread == pthread_self();
#endif
@ -849,6 +849,10 @@ namespace libtorrent
// the main working thread
boost::scoped_ptr<thread> m_thread;
#if defined TORRENT_DEBUG && defined BOOST_HAS_PTHREADS
pthread_t m_network_thread;
#endif
};
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING

View File

@ -342,6 +342,8 @@ namespace libtorrent
#endif
start_lsd();
}
m_impl->start_session();
}
session::~session()

View File

@ -512,6 +512,9 @@ namespace aux {
#endif
, m_total_failed_bytes(0)
, m_total_redundant_bytes(0)
#if defined TORRENT_DEBUG && defined BOOST_HAS_PTHREADS
, m_network_thread(0)
#endif
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
m_logger = create_log("main_session", listen_port(), false);
@ -815,17 +818,20 @@ namespace aux {
update_rate_settings();
update_connections_limit();
update_unchoke_limit();
}
void session_impl::start_session()
{
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
(*m_logger) << time_now_string() << " spawning network thread\n";
#endif
m_thread.reset(new thread(boost::bind(&session_impl::main_thread, this)));
}
void session_impl::start()
void session_impl::init()
{
#if defined TORRENT_LOGGING || defined TORRENT_VERBOSE_LOGGING
(*m_logger) << time_now_string() << " *** session start\n";
(*m_logger) << time_now_string() << " *** session thread init\n";
#endif
// this is where we should set up all async operations. This
@ -1308,6 +1314,7 @@ namespace aux {
void session_impl::set_settings(session_settings const& s)
{
INVARIANT_CHECK;
TORRENT_ASSERT(is_network_thread());
TORRENT_ASSERT_VAL(s.file_pool_size > 0, s.file_pool_size);
@ -1915,6 +1922,8 @@ namespace aux {
void session_impl::incoming_connection(boost::shared_ptr<socket_type> const& s)
{
TORRENT_ASSERT(is_network_thread());
error_code ec;
// we got a connection request!
tcp::endpoint endp = s->remote_endpoint(ec);
@ -2091,6 +2100,8 @@ namespace aux {
void session_impl::close_connection(peer_connection const* p
, error_code const& ec)
{
TORRENT_ASSERT(is_network_thread());
// too expensive
// INVARIANT_CHECK;
@ -2946,6 +2957,7 @@ namespace aux {
void session_impl::recalculate_optimistic_unchoke_slots()
{
TORRENT_ASSERT(is_network_thread());
if (m_allowed_upload_slots == 0) return;
std::vector<policy::peer*> opt_unchoke;
@ -3037,6 +3049,7 @@ namespace aux {
void session_impl::recalculate_unchoke_slots(int congested_torrents
, int uncongested_torrents)
{
TORRENT_ASSERT(is_network_thread());
INVARIANT_CHECK;
ptime now = time_now();
@ -3273,16 +3286,14 @@ namespace aux {
void session_impl::main_thread()
{
#ifdef TORRENT_DEBUG
#if defined BOOST_HAS_PTHREADS
#if defined TORRENT_DEBUG && defined BOOST_HAS_PTHREADS
m_network_thread = pthread_self();
#endif
#endif
TORRENT_ASSERT(is_network_thread());
eh_initializer();
// initialize async operations
start();
init();
bool stop_loop = false;
while (!stop_loop)
@ -3322,6 +3333,10 @@ namespace aux {
TORRENT_ASSERT(m_torrents.empty());
TORRENT_ASSERT(m_connections.empty());
#if defined TORRENT_DEBUG && defined BOOST_HAS_PTHREADS
m_network_thread = 0;
#endif
}
@ -3688,6 +3703,7 @@ namespace aux {
session_status session_impl::status() const
{
// INVARIANT_CHECK;
TORRENT_ASSERT(is_network_thread());
session_status s;
@ -4353,6 +4369,8 @@ namespace aux {
#if defined TORRENT_STATS && defined TORRENT_DISK_STATS
void session_impl::log_buffer_usage()
{
TORRENT_ASSERT(is_network_thread());
int send_buffer_capacity = 0;
int used_send_buffer = 0;
for (connection_map::const_iterator i = m_connections.begin()
@ -4393,6 +4411,8 @@ namespace aux {
#ifdef TORRENT_DEBUG
void session_impl::check_invariant() const
{
TORRENT_ASSERT(is_network_thread());
int num_checking = 0;
for (check_queue_t::const_iterator i = m_queued_for_checking.begin()
, end(m_queued_for_checking.end()); i != end; ++i)

View File

@ -395,6 +395,7 @@ namespace libtorrent
, m_interface_index(0)
, m_graceful_pause_mode(false)
{
TORRENT_ASSERT(m_ses.is_network_thread());
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
(*m_ses.m_logger) << time_now_string() << " creating torrent: "
<< torrent_file().name() << "\n";
@ -437,6 +438,7 @@ namespace libtorrent
void torrent::start()
{
TORRENT_ASSERT(m_ses.is_network_thread());
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
(*m_ses.m_logger) << time_now_string() << " starting torrent: "
<< torrent_file().name() << "\n";
@ -485,6 +487,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_DHT
bool torrent::should_announce_dht() const
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (m_ses.m_listen_sockets.empty()) return false;
if (!m_ses.m_dht) return false;
@ -508,6 +511,7 @@ namespace libtorrent
torrent::~torrent()
{
TORRENT_ASSERT(m_ses.is_network_thread());
// The invariant can't be maintained here, since the torrent
// is being destructed, all weak references to it have been
// reset, which means that all its peers already have an
@ -627,6 +631,7 @@ namespace libtorrent
void torrent::handle_disk_error(disk_io_job const& j, peer_connection* c)
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (!j.error) return;
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -721,6 +726,7 @@ namespace libtorrent
void torrent::add_piece(int piece, char const* data, int flags)
{
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(piece >= 0 && piece < m_torrent_file->num_pieces());
int piece_size = m_torrent_file->piece_size(piece);
int blocks_in_piece = (piece_size + block_size() - 1) / block_size();
@ -864,6 +870,7 @@ namespace libtorrent
// shared_from_this()
void torrent::init()
{
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(m_torrent_file->is_valid());
TORRENT_ASSERT(m_torrent_file->num_files() > 0);
TORRENT_ASSERT(m_torrent_file->total_size() >= 0);
@ -1225,6 +1232,7 @@ namespace libtorrent
void torrent::queue_torrent_check()
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (m_queued_for_checking) return;
m_queued_for_checking = true;
m_ses.queue_check_torrent(shared_from_this());
@ -1232,6 +1240,7 @@ namespace libtorrent
void torrent::dequeue_torrent_check()
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (!m_queued_for_checking) return;
m_queued_for_checking = false;
m_ses.dequeue_check_torrent(shared_from_this());
@ -1426,6 +1435,7 @@ namespace libtorrent
void torrent::dht_announce()
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (!m_ses.m_dht) return;
if (!should_announce_dht()) return;
@ -1447,6 +1457,7 @@ namespace libtorrent
void torrent::on_dht_announce_response(std::vector<tcp::endpoint> const& peers)
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (peers.empty()) return;
if (m_ses.m_alerts.should_post<dht_reply_alert>())
@ -1468,6 +1479,7 @@ namespace libtorrent
void torrent::announce_with_tracker(tracker_request::event_t e
, address const& bind_interface)
{
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
if (m_trackers.empty()) return;
@ -1634,6 +1646,7 @@ namespace libtorrent
void torrent::scrape_tracker()
{
TORRENT_ASSERT(m_ses.is_network_thread());
m_last_scrape = 0;
if (m_trackers.empty()) return;
@ -2220,6 +2233,7 @@ namespace libtorrent
// -2: piece failed check
void torrent::piece_finished(int index, int passed_hash_check)
{
TORRENT_ASSERT(m_ses.is_network_thread());
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING
(*m_ses.m_logger) << time_now_string() << " *** PIECE_FINISHED [ p: "
<< index << " chk: " << ((passed_hash_check == 0)
@ -2276,6 +2290,7 @@ namespace libtorrent
void torrent::we_have(int index)
{
TORRENT_ASSERT(m_ses.is_network_thread());
// update m_file_progress
TORRENT_ASSERT(m_picker);
TORRENT_ASSERT(!have_piece(index));
@ -2323,6 +2338,7 @@ namespace libtorrent
void torrent::piece_passed(int index)
{
// INVARIANT_CHECK;
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < m_torrent_file->num_pieces());
@ -2451,6 +2467,7 @@ namespace libtorrent
// invariant check here since it assumes:
// (total_done == m_torrent_file->total_size()) => is_seed()
INVARIANT_CHECK;
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(m_storage);
TORRENT_ASSERT(m_storage->refcount() > 0);
@ -2596,6 +2613,7 @@ namespace libtorrent
void torrent::abort()
{
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
if (m_abort) return;
@ -3313,6 +3331,7 @@ namespace libtorrent
// INVARIANT_CHECK;
TORRENT_ASSERT(p != 0);
TORRENT_ASSERT(m_ses.is_network_thread());
peer_iterator i = m_connections.find(p);
if (i == m_connections.end())
@ -3378,6 +3397,7 @@ namespace libtorrent
void torrent::connect_to_url_seed(std::list<web_seed_entry>::iterator web)
{
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
TORRENT_ASSERT(!web->resolving);
@ -3593,6 +3613,7 @@ namespace libtorrent
void torrent::connect_web_seed(std::list<web_seed_entry>::iterator web, tcp::endpoint const& a)
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{
if (m_ses.m_alerts.should_post<peer_blocked_alert>())
@ -3726,6 +3747,7 @@ namespace libtorrent
void torrent::resolve_peer_country(boost::intrusive_ptr<peer_connection> const& p) const
{
TORRENT_ASSERT(m_ses.is_network_thread());
if (m_resolving_country
|| is_local(p->remote().address())
|| p->has_country()
@ -4319,6 +4341,7 @@ namespace libtorrent
void torrent::get_download_queue(std::vector<partial_piece_info>& queue)
{
TORRENT_ASSERT(m_ses.is_network_thread());
queue.clear();
std::vector<block_info>& blk = m_ses.m_block_info_storage;
blk.clear();
@ -4398,6 +4421,7 @@ namespace libtorrent
bool torrent::connect_to_peer(policy::peer* peerinfo, bool ignore_limit)
{
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
TORRENT_ASSERT(peerinfo);
@ -4531,6 +4555,7 @@ namespace libtorrent
bool torrent::set_metadata(char const* metadata_buf, int metadata_size)
{
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
if (m_torrent_file->is_valid()) return false;
@ -4989,6 +5014,7 @@ namespace libtorrent
alert_manager& torrent::alerts() const
{
TORRENT_ASSERT(m_ses.is_network_thread());
return m_ses.m_alerts;
}
@ -5726,6 +5752,7 @@ namespace libtorrent
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING || defined TORRENT_LOGGING
void torrent::log_to_all_peers(char const* message)
{
TORRENT_ASSERT(m_ses.is_network_thread());
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
for (peer_iterator i = m_connections.begin();
i != m_connections.end(); ++i)
@ -6751,6 +6778,7 @@ namespace libtorrent
void torrent::set_state(torrent_status::state_t s)
{
TORRENT_ASSERT(m_ses.is_network_thread());
#ifdef TORRENT_DEBUG
if (s != torrent_status::checking_files
&& s != torrent_status::queued_for_checking)
@ -6974,6 +7002,7 @@ namespace libtorrent
void torrent::add_redundant_bytes(int b)
{
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(b > 0);
m_total_redundant_bytes += b;
m_ses.add_redundant_bytes(b);
@ -6983,6 +7012,7 @@ namespace libtorrent
void torrent::add_failed_bytes(int b)
{
TORRENT_ASSERT(m_ses.is_network_thread());
TORRENT_ASSERT(b > 0);
m_total_failed_bytes += b;
m_ses.add_failed_bytes(b);
@ -6992,6 +7022,7 @@ namespace libtorrent
int torrent::num_seeds() const
{
TORRENT_ASSERT(m_ses.is_network_thread());
INVARIANT_CHECK;
int ret = 0;
@ -7048,6 +7079,7 @@ namespace libtorrent
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
void torrent::debug_log(const std::string& line)
{
TORRENT_ASSERT(m_ses.is_network_thread());
(*m_ses.m_logger) << time_now_string() << " " << line << "\n";
}
#endif