more improvement to error/exception handling (#1247)

improvement to error/exception handling
This commit is contained in:
Arvid Norberg 2016-10-22 22:00:47 -04:00 committed by GitHub
parent a6e5ba8804
commit 5341be1e84
6 changed files with 183 additions and 193 deletions

View File

@ -450,6 +450,7 @@ namespace libtorrent
ip_filter const* get_ip_filter() { return m_ip_filter.get(); }
std::string resolve_filename(int file) const;
void handle_exception();
void handle_disk_error(disk_io_job const* j, peer_connection* c = 0);
void clear_error();

View File

@ -3520,13 +3520,12 @@ namespace libtorrent
TORRENT_ASSERT(m_job_completions_in_flight);
m_job_completions_in_flight = false;
int const num_jobs = m_completed_jobs.size();
disk_io_job* j = m_completed_jobs.get_all();
l.unlock();
uncork_interface* uncork = static_cast<uncork_interface*>(userdata);
std::vector<disk_io_job*> to_delete;
to_delete.reserve(num_jobs);
std::array<disk_io_job*, 64> to_delete;
int cnt = 0;
while (j)
{
@ -3539,12 +3538,16 @@ namespace libtorrent
j->callback_called = true;
#endif
if (j->callback) j->callback(j);
to_delete.push_back(j);
to_delete[cnt++] = j;
j = next;
if (cnt == to_delete.size())
{
cnt = 0;
free_jobs(to_delete.data(), int(to_delete.size()));
}
}
if (!to_delete.empty())
free_jobs(&to_delete[0], int(to_delete.size()));
if (cnt > 0) free_jobs(to_delete.data(), cnt);
// uncork all peers who received a disk event. This is
// to coalesce all the socket writes caused by the events.

View File

@ -279,9 +279,7 @@ void lsd::on_announce(udp::endpoint const& from, char const* buf
}
#endif
// we got an announce, pass it on through the callback
TORRENT_TRY {
m_callback.on_lsd_peer(tcp::endpoint(from.address(), port), ih);
} TORRENT_CATCH (std::exception const&) {}
}
}
}

View File

@ -1091,9 +1091,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto const& e : m_extensions)
{
TORRENT_TRY {
e->on_piece_pass(index);
} TORRENT_CATCH (std::exception const&) {}
}
#else
TORRENT_UNUSED(index);
@ -1111,9 +1109,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto const& e : m_extensions)
{
TORRENT_TRY {
e->on_piece_failed(index);
} TORRENT_CATCH (std::exception const&) {}
}
#else
TORRENT_UNUSED(index);

View File

@ -666,9 +666,7 @@ namespace aux {
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto const& ext : m_ses_extensions[plugins_all_idx])
{
TORRENT_TRY {
ext->save_state(*eptr);
} TORRENT_CATCH (std::exception const&) {}
}
#endif
}
@ -776,9 +774,7 @@ namespace aux {
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_ses_extensions[plugins_all_idx])
{
TORRENT_TRY {
ext->load_state(*e);
} TORRENT_CATCH (std::exception const&) {}
}
#endif
}
@ -3062,9 +3058,7 @@ namespace aux {
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_ses_extensions[plugins_tick_idx])
{
TORRENT_TRY {
ext->on_tick();
} TORRENT_CATCH (std::exception const&) {}
}
#endif
@ -3981,24 +3975,12 @@ namespace aux {
TORRENT_ASSERT(t->want_peers());
TORRENT_ASSERT(!t->is_torrent_paused());
TORRENT_TRY
{
if (t->try_connect_peer())
{
--max_connections;
steps_since_last_connect = 0;
m_stats_counters.inc_stats_counter(counters::connection_attempts);
}
}
TORRENT_CATCH(std::bad_alloc&)
{
// we ran out of memory trying to connect to a peer
// lower the global limit to the number of peers
// we already have
m_settings.set_int(settings_pack::connections_limit, num_connections());
if (m_settings.get_int(settings_pack::connections_limit) < 2)
m_settings.set_int(settings_pack::connections_limit, 2);
}
++steps_since_last_connect;
@ -4174,11 +4156,8 @@ namespace aux {
{
m_stats_counters.inc_stats_counter(counters::on_disk_counter);
TORRENT_ASSERT(is_single_thread());
for (std::vector<peer_connection*>::iterator i = m_delayed_uncorks.begin()
, end(m_delayed_uncorks.end()); i != end; ++i)
{
(*i)->uncork_socket();
}
for (peer_connection* p : m_delayed_uncorks)
p->uncork_socket();
m_delayed_uncorks.clear();
}

View File

@ -388,7 +388,7 @@ namespace libtorrent
#ifndef TORRENT_NO_DEPRECATE
// deprecated in 1.2
void torrent::on_torrent_download(error_code const& ec
, http_parser const& parser, char const* data, int size)
, http_parser const& parser, char const* data, int size) try
{
if (m_abort) return;
@ -495,6 +495,7 @@ namespace libtorrent
init();
}
catch (...) { handle_exception(); }
#endif // TORRENT_NO_DEPRECATE
@ -994,6 +995,47 @@ namespace libtorrent
m_peer_list.reset(new peer_list);
}
void torrent::handle_exception()
{
try
{
throw;
}
catch (system_error const& err)
{
#ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{
debug_log("torrent exception: (%d) %s: %s"
, err.code().value(), err.code().message().c_str()
, err.what());
}
#endif
set_error(err.code(), torrent_status::error_file_exception);
}
catch (std::exception const& err)
{
TORRENT_UNUSED(err);
set_error(error_code(), torrent_status::error_file_exception);
#ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{
debug_log("torrent exception: %s", err.what());
}
#endif
}
catch (...)
{
set_error(error_code(), torrent_status::error_file_exception);
#ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{
debug_log("torrent exception: unknown");
}
#endif
}
}
void torrent::handle_disk_error(disk_io_job const* j, peer_connection* c)
{
TORRENT_ASSERT(is_single_thread());
@ -1096,7 +1138,7 @@ namespace libtorrent
pause();
}
void torrent::on_piece_fail_sync(disk_io_job const* j, piece_block b)
void torrent::on_piece_fail_sync(disk_io_job const* j, piece_block b) try
{
TORRENT_UNUSED(j);
TORRENT_UNUSED(b);
@ -1125,9 +1167,10 @@ namespace libtorrent
}
}
}
catch (...) { handle_exception(); }
void torrent::on_disk_read_complete(disk_io_job const* j, peer_request r
, std::shared_ptr<read_piece_struct> rp)
, std::shared_ptr<read_piece_struct> rp) try
{
// hold a reference until this function returns
TORRENT_ASSERT(is_single_thread());
@ -1161,6 +1204,7 @@ namespace libtorrent
}
}
}
catch (...) { handle_exception(); }
storage_mode_t torrent::storage_mode() const
{ return storage_mode_t(m_storage_mode); }
@ -1186,13 +1230,17 @@ namespace libtorrent
|| settings().get_int(settings_pack::suggest_mode)
== settings_pack::suggest_read_cache);
m_picker.reset(new piece_picker());
std::unique_ptr<piece_picker> pp(new piece_picker());
int const blocks_per_piece
= (m_torrent_file->piece_length() + block_size() - 1) / block_size();
int const blocks_in_last_piece
= ((m_torrent_file->total_size() % m_torrent_file->piece_length())
+ block_size() - 1) / block_size();
m_picker->init(blocks_per_piece, blocks_in_last_piece, m_torrent_file->num_pieces());
// TODO: 3 the init function should be merged with the constructor
pp->init(blocks_per_piece, blocks_in_last_piece, m_torrent_file->num_pieces());
m_picker = std::move(pp);
// initialize the file progress too
if (m_file_progress.empty())
@ -1283,7 +1331,7 @@ namespace libtorrent
}
void torrent::on_disk_write_complete(disk_io_job const* j
, peer_request p)
, peer_request p) try
{
TORRENT_ASSERT(is_single_thread());
@ -1321,8 +1369,9 @@ namespace libtorrent
, int(block_finished.piece_index));
}
}
catch (...) { handle_exception(); }
void torrent::on_disk_tick_done(disk_io_job const* j)
void torrent::on_disk_tick_done(disk_io_job const* j) try
{
if (j->ret && m_storage_tick == 0)
{
@ -1330,6 +1379,7 @@ namespace libtorrent
update_want_tick();
}
}
catch (...) { handle_exception(); }
bool torrent::add_merkle_nodes(std::map<int, sha1_hash> const& nodes, int piece)
{
@ -1894,15 +1944,15 @@ namespace libtorrent
}
#endif // TORRENT_DISABLE_MUTABLE_TORRENTS
#if TORRENT_USE_ASSERTS
TORRENT_ASSERT(m_outstanding_check_files == false);
m_outstanding_check_files = true;
#endif
m_ses.disk_thread().async_check_files(
m_storage.get(), m_add_torrent_params ? m_add_torrent_params.get() : nullptr
, links, std::bind(&torrent::on_resume_data_checked
, shared_from_this(), _1));
// async_check_files will gut links
#if TORRENT_USE_ASSERTS
TORRENT_ASSERT(m_outstanding_check_files == false);
m_outstanding_check_files = true;
#endif
#ifndef TORRENT_DISABLE_LOGGING
debug_log("init, async_check_files");
#endif
@ -1911,6 +1961,7 @@ namespace libtorrent
maybe_done_flushing();
}
bt_peer_connection* torrent::find_introducer(tcp::endpoint const& ep) const
{
#ifndef TORRENT_DISABLE_EXTENSIONS
@ -1946,7 +1997,7 @@ namespace libtorrent
return nullptr;
}
void torrent::on_resume_data_checked(disk_io_job const* j)
void torrent::on_resume_data_checked(disk_io_job const* j) try
{
// hold a reference until this function returns
@ -2148,6 +2199,7 @@ namespace libtorrent
// function.
m_need_save_resume_data = need_save_resume_data;
}
catch (...) { handle_exception(); }
void torrent::force_recheck()
{
@ -2180,8 +2232,8 @@ namespace libtorrent
// instead, just clear which pieces we have
if (m_picker)
{
int blocks_per_piece = (m_torrent_file->piece_length() + block_size() - 1) / block_size();
int blocks_in_last_piece = ((m_torrent_file->total_size() % m_torrent_file->piece_length())
int const blocks_per_piece = (m_torrent_file->piece_length() + block_size() - 1) / block_size();
int const blocks_in_last_piece = ((m_torrent_file->total_size() % m_torrent_file->piece_length())
+ block_size() - 1) / block_size();
m_picker->init(blocks_per_piece, blocks_in_last_piece, m_torrent_file->num_pieces());
}
@ -2209,7 +2261,7 @@ namespace libtorrent
, shared_from_this(), _1));
}
void torrent::on_force_recheck(disk_io_job const* j)
void torrent::on_force_recheck(disk_io_job const* j) try
{
TORRENT_ASSERT(is_single_thread());
@ -2240,6 +2292,7 @@ namespace libtorrent
else m_ses.trigger_auto_manage();
}
}
catch (...) { handle_exception(); }
void torrent::start_checking()
{
@ -2282,7 +2335,7 @@ namespace libtorrent
// This is only used for checking of torrents. i.e. force-recheck or initial checking
// of existing files
void torrent::on_piece_hashed(disk_io_job const* j)
void torrent::on_piece_hashed(disk_io_job const* j) try
{
TORRENT_ASSERT(is_single_thread());
INVARIANT_CHECK;
@ -2425,6 +2478,7 @@ namespace libtorrent
m_checking_piece = 0;
m_num_checked_pieces = 0;
}
catch (...) { handle_exception(); }
#ifndef TORRENT_NO_DEPRECATE
void torrent::use_interface(std::string net_interfaces)
@ -2435,7 +2489,7 @@ namespace libtorrent
}
#endif
void torrent::on_tracker_announce(error_code const& ec)
void torrent::on_tracker_announce(error_code const& ec) try
{
COMPLETE_ASYNC("tracker::on_tracker_announce");
TORRENT_ASSERT(is_single_thread());
@ -2445,6 +2499,7 @@ namespace libtorrent
if (m_abort) return;
announce_with_tracker();
}
catch (...) { handle_exception(); }
void torrent::lsd_announce()
{
@ -2574,7 +2629,7 @@ namespace libtorrent
tor->on_dht_announce_response(peers);
}
void torrent::on_dht_announce_response(std::vector<tcp::endpoint> const& peers)
void torrent::on_dht_announce_response(std::vector<tcp::endpoint> const& peers) try
{
TORRENT_ASSERT(is_single_thread());
@ -2603,6 +2658,7 @@ namespace libtorrent
update_want_peers();
}
catch (...) { handle_exception(); }
#endif
@ -3301,7 +3357,7 @@ namespace libtorrent
#endif
#if TORRENT_USE_I2P
void torrent::on_i2p_resolve(error_code const& ec, char const* dest)
void torrent::on_i2p_resolve(error_code const& ec, char const* dest) try
{
TORRENT_ASSERT(is_single_thread());
@ -3320,10 +3376,11 @@ namespace libtorrent
state_updated();
peers_erased(st.erased);
}
catch (...) { handle_exception(); }
#endif
void torrent::on_peer_name_lookup(error_code const& e
, std::vector<address> const& host_list, int port)
, std::vector<address> const& host_list, int port) try
{
TORRENT_ASSERT(is_single_thread());
@ -3360,6 +3417,7 @@ namespace libtorrent
state_updated();
update_want_peers();
}
catch (...) { handle_exception(); }
std::int64_t torrent::bytes_left() const
{
@ -3665,7 +3723,7 @@ namespace libtorrent
TORRENT_ASSERT(st.total_done >= st.total_wanted_done);
}
void torrent::on_piece_verified(disk_io_job const* j)
void torrent::on_piece_verified(disk_io_job const* j) try
{
TORRENT_ASSERT(is_single_thread());
@ -3740,8 +3798,8 @@ namespace libtorrent
TORRENT_ASSERT(ret == -1);
update_gauge();
}
}
catch (...) { handle_exception(); }
void torrent::add_suggest_piece(int const index)
{
@ -4177,7 +4235,7 @@ namespace libtorrent
c.send_block_requests();
}
void torrent::on_piece_sync(disk_io_job const* j)
void torrent::on_piece_sync(disk_io_job const* j) try
{
// the user may have called force_recheck, which clears
// the piece picker
@ -4217,6 +4275,7 @@ namespace libtorrent
}
}
}
catch (...) { handle_exception(); }
void torrent::peer_has(int index, peer_connection const* peer)
{
@ -4412,7 +4471,7 @@ namespace libtorrent
return avail_vec[random(avail_vec.size() - 1)];
}
void torrent::on_files_deleted(disk_io_job const* j)
void torrent::on_files_deleted(disk_io_job const* j) try
{
TORRENT_ASSERT(is_single_thread());
@ -4427,8 +4486,9 @@ namespace libtorrent
alerts().emplace_alert<torrent_deleted_alert>(get_handle(), m_torrent_file->info_hash());
}
}
catch (...) { handle_exception(); }
void torrent::on_file_renamed(disk_io_job const* j)
void torrent::on_file_renamed(disk_io_job const* j) try
{
TORRENT_ASSERT(is_single_thread());
@ -4446,14 +4506,16 @@ namespace libtorrent
, j->piece, j->error.ec);
}
}
catch (...) { handle_exception(); }
void torrent::on_torrent_paused(disk_io_job const*)
void torrent::on_torrent_paused(disk_io_job const*) try
{
TORRENT_ASSERT(is_single_thread());
if (alerts().should_post<torrent_paused_alert>())
alerts().emplace_alert<torrent_paused_alert>(get_handle());
}
catch (...) { handle_exception(); }
#ifndef TORRENT_NO_DEPRECATE
std::string torrent::tracker_login() const
@ -5741,7 +5803,7 @@ namespace libtorrent
void torrent::on_proxy_name_lookup(error_code const& e
, std::vector<address> const& addrs
, std::list<web_seed_t>::iterator web, int port)
, std::list<web_seed_t>::iterator web, int port) try
{
TORRENT_ASSERT(is_single_thread());
@ -5823,11 +5885,12 @@ namespace libtorrent
self->wrap(&torrent::on_name_lookup, err, addr, port, web);
});
}
catch (...) { handle_exception(); }
void torrent::on_name_lookup(error_code const& e
, std::vector<address> const& addrs
, int port
, std::list<web_seed_t>::iterator web)
, std::list<web_seed_t>::iterator web) try
{
TORRENT_ASSERT(is_single_thread());
@ -5884,6 +5947,7 @@ namespace libtorrent
connect_web_seed(web, web->endpoints.front());
}
catch (...) { handle_exception(); }
void torrent::connect_web_seed(std::list<web_seed_t>::iterator web, tcp::endpoint a)
{
@ -6022,8 +6086,6 @@ namespace libtorrent
}
#endif
TORRENT_TRY
{
TORRENT_ASSERT(!c->m_in_constructor);
// add the newly connected peer to this torrent's peer list
sorted_insert(m_connections, c.get());
@ -6064,16 +6126,6 @@ namespace libtorrent
, num_peers());
#endif
}
TORRENT_CATCH (std::exception const& e)
{
TORRENT_DECLARE_DUMMY(std::exception, e);
(void)e;
#ifndef TORRENT_DISABLE_LOGGING
debug_log("*** PEER_ERROR: %s", e.what());
#endif
c->disconnect(errors::no_error, op_bittorrent, 1);
}
}
std::shared_ptr<const torrent_info> torrent::get_torrent_copy()
{
@ -6709,11 +6761,9 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto const& ext : m_extensions)
{
TORRENT_TRY {
std::shared_ptr<peer_plugin> pp(ext->new_connection(
peer_connection_handle(c->self())));
if (pp) c->add_extension(pp);
} TORRENT_CATCH (std::exception const&) {}
}
#endif
@ -6995,8 +7045,6 @@ namespace libtorrent
}
}
TORRENT_TRY
{
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_extensions)
{
@ -7024,22 +7072,7 @@ namespace libtorrent
return false;
}
peers_erased(st.erased);
update_want_peers();
}
TORRENT_CATCH (std::exception const& e)
{
TORRENT_DECLARE_DUMMY(std::exception, e);
(void)e;
#ifndef TORRENT_DISABLE_LOGGING
if (should_log())
{
debug_log("CLOSING CONNECTION \"%s\" caught exception: %s"
, print_endpoint(p->remote()).c_str(), e.what());
}
#endif
p->disconnect(errors::no_error, op_bittorrent);
return false;
}
TORRENT_ASSERT(sorted_find(m_connections, p) == m_connections.end());
sorted_insert(m_connections, p);
update_want_peers();
@ -7653,9 +7686,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_extensions)
{
TORRENT_TRY {
ext->on_files_checked();
} TORRENT_CATCH (std::exception const&) {}
}
#endif
@ -7811,7 +7842,7 @@ namespace libtorrent
}
}
void torrent::on_storage_moved(disk_io_job const* j)
void torrent::on_storage_moved(disk_io_job const* j) try
{
TORRENT_ASSERT(is_single_thread());
@ -7832,6 +7863,7 @@ namespace libtorrent
, resolve_filename(j->error.file), j->error.operation_str());
}
}
catch (...) { handle_exception(); }
piece_manager& torrent::storage()
{
@ -8298,7 +8330,7 @@ namespace libtorrent
if (file == torrent_status::error_file_url) return m_url;
#endif
if (file == torrent_status::error_file_ssl_ctx) return "SSL Context";
if (file == torrent_status::error_file_metadata) return "metadata (from user load function)";
if (file == torrent_status::error_file_exception) return "exception";
if (m_storage && file >= 0)
{
@ -8311,7 +8343,7 @@ namespace libtorrent
}
}
void torrent::set_error(error_code const& ec, int error_file)
void torrent::set_error(error_code const& ec, int const error_file)
{
TORRENT_ASSERT(is_single_thread());
m_error = ec;
@ -8562,7 +8594,7 @@ namespace libtorrent
, std::bind(&torrent::on_cache_flushed, shared_from_this(), _1));
}
void torrent::on_cache_flushed(disk_io_job const*)
void torrent::on_cache_flushed(disk_io_job const*) try
{
TORRENT_ASSERT(is_single_thread());
@ -8571,6 +8603,7 @@ namespace libtorrent
if (alerts().should_post<cache_flushed_alert>())
alerts().emplace_alert<cache_flushed_alert>(get_handle());
}
catch (...) { handle_exception(); }
bool torrent::is_paused() const
{
@ -8610,9 +8643,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_extensions)
{
TORRENT_TRY {
if (ext->on_pause()) return;
} TORRENT_CATCH (std::exception const&) {}
}
#endif
@ -8847,9 +8878,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_extensions)
{
TORRENT_TRY {
if (ext->on_resume()) return;
} TORRENT_CATCH (std::exception const&) {}
}
#endif
@ -9085,9 +9114,7 @@ namespace libtorrent
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto const& ext : m_extensions)
{
TORRENT_TRY {
ext->tick();
} TORRENT_CATCH (std::exception const&) {}
}
if (m_abort) return;
@ -9200,18 +9227,7 @@ namespace libtorrent
// updates the peer connection's ul/dl bandwidth
// resource requests
TORRENT_TRY {
p->second_tick(tick_interval_ms);
}
TORRENT_CATCH (std::exception const& e)
{
TORRENT_DECLARE_DUMMY(std::exception, e);
(void)e;
#ifndef TORRENT_DISABLE_LOGGING
p->peer_log(peer_log_alert::info, "ERROR", "%s", e.what());
#endif
p->disconnect(errors::no_error, op_bittorrent, 1);
}
if (p->is_disconnecting())
{
@ -9270,7 +9286,7 @@ namespace libtorrent
< settings().get_int(settings_pack::inactive_down_rate);
}
void torrent::on_inactivity_tick(error_code const& ec)
void torrent::on_inactivity_tick(error_code const& ec) try
{
m_pending_active_change = false;
@ -9287,6 +9303,7 @@ namespace libtorrent
if (settings().get_bool(settings_pack::dont_count_slow_torrents))
m_ses.trigger_auto_manage();
}
catch (...) { handle_exception(); }
void torrent::maybe_connect_web_seeds()
{
@ -10635,18 +10652,16 @@ namespace libtorrent
debug_log("set_state() %d", m_state);
#endif
update_gauge();
update_want_peers();
update_state_list();
update_gauge();
state_updated();
#ifndef TORRENT_DISABLE_EXTENSIONS
for (auto& ext : m_extensions)
{
TORRENT_TRY {
ext->on_state(m_state);
} TORRENT_CATCH (std::exception const&) {}
}
#endif
}
@ -10657,9 +10672,7 @@ namespace libtorrent
{
for (auto& ext : m_extensions)
{
TORRENT_TRY {
ext->on_add_peer(ip, src, flags);
} TORRENT_CATCH (std::exception const&) {}
}
}
#endif