diff --git a/ChangeLog b/ChangeLog index b19102530..91d5c2911 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * report errors in read_piece_alert * DHT memory optimization * improve DHT lookup speed * improve support for windows XP and earlier diff --git a/docs/manual.rst b/docs/manual.rst index afacc1984..f1c1902da 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -6314,6 +6314,10 @@ e.g:: case read_piece_alert::alert_type: { read_piece_alert* p = (read_piece_alert*)a.get(); + if (p->ec) { + // read_piece failed + break; + } // use p break; } @@ -6432,11 +6436,14 @@ is 0. If successful, ``buffer`` points to a buffer containing all the data of the piece. ``piece`` is the piece index that was read. ``size`` is the number of bytes that was read. +If the operation fails, ec will indicat what went wrong. + :: struct read_piece_alert: torrent_alert { // ... + error_code ec; boost::shared_ptr buffer; int piece; int size; diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index c98c3f4fc..5d224e602 100644 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -145,12 +145,20 @@ namespace libtorrent , size(s) {} + read_piece_alert(torrent_handle h, int p, error_code e) + : torrent_alert(h) + , ec(e) + , piece(p) + , size(0) + {} + TORRENT_DEFINE_ALERT(read_piece_alert); const static int static_category = alert::storage_notification; virtual std::string message() const; virtual bool discardable() const { return false; } + error_code ec; boost::shared_array buffer; int piece; int size; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 8dee396cd..b5789433a 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -191,6 +191,7 @@ namespace libtorrent boost::shared_array piece_data; int blocks_left; bool fail; + error_code error; }; void read_piece(int piece); void on_disk_read_complete(int ret, disk_io_job const& j, peer_request r, read_piece_struct* rp); diff --git a/src/alert.cpp b/src/alert.cpp index bbddf7194..2ada5ce0c 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -79,8 +79,16 @@ namespace libtorrent { std::string read_piece_alert::message() const { char msg[200]; - snprintf(msg, sizeof(msg), "%s: piece %s %u", torrent_alert::message().c_str() - , buffer ? "successful" : "failed", piece); + if (ec) + { + snprintf(msg, sizeof(msg), "%s: read_piece %u failed: %s" + , torrent_alert::message().c_str() , piece, ec.message().c_str()); + } + else + { + snprintf(msg, sizeof(msg), "%s: read_piece %u successful" + , torrent_alert::message().c_str() , piece); + } return msg; } diff --git a/src/torrent.cpp b/src/torrent.cpp index c358b3f0a..46aae4e59 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -939,13 +939,8 @@ namespace libtorrent if (m_abort) { // failed - // TODO: 3 add an error code to the read_piece alert - // to indicate what went wrong. operation_aborted in this - // case. It also has to be included in the cases where - // a time_critical_piece is aborted by setting its priority - // to zero. m_ses.m_alerts.post_alert(read_piece_alert( - get_handle(), piece, boost::shared_array(), 0)); + get_handle(), piece, error_code(boost::system::errc::operation_canceled, get_system_category()))); return; } @@ -1137,6 +1132,7 @@ namespace libtorrent if (ret != r.length) { rp->fail = true; + rp->error = j.error; handle_disk_error(j); } else @@ -1149,12 +1145,14 @@ namespace libtorrent int size = m_torrent_file->piece_size(r.piece); if (rp->fail) { - rp->piece_data.reset(); - size = 0; + m_ses.m_alerts.post_alert(read_piece_alert( + get_handle(), r.piece, rp->error)); + } + else + { + m_ses.m_alerts.post_alert(read_piece_alert( + get_handle(), r.piece, rp->piece_data, size)); } - - m_ses.m_alerts.post_alert(read_piece_alert( - get_handle(), r.piece, rp->piece_data, size)); delete rp; } } @@ -3705,7 +3703,7 @@ namespace libtorrent if (flags & torrent_handle::alert_when_available) { m_ses.m_alerts.post_alert(read_piece_alert( - get_handle(), piece, boost::shared_array(), 0)); + get_handle(), piece, error_code(boost::system::errc::operation_canceled, get_system_category()))); } return; } @@ -3821,7 +3819,7 @@ namespace libtorrent { // post an empty read_piece_alert to indicate it failed m_ses.m_alerts.post_alert(read_piece_alert( - get_handle(), piece, boost::shared_array(), 0)); + get_handle(), piece, error_code(boost::system::errc::operation_canceled, get_system_category()))); } m_time_critical_pieces.erase(i); return; @@ -3840,7 +3838,7 @@ namespace libtorrent { // post an empty read_piece_alert to indicate it failed m_ses.m_alerts.post_alert(read_piece_alert( - get_handle(), i->piece, boost::shared_array(), 0)); + get_handle(), i->piece, error_code(boost::system::errc::operation_canceled, get_system_category()))); } i = m_time_critical_pieces.erase(i); continue;