add asynchronous overload of torrent_handle::add_piece()
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
|
||||
* add asynchronous overload of torrent_handle::add_piece()
|
||||
* default to a single hashing thread, for full checks
|
||||
* Fix bug when checking files and the first piece is invalid
|
||||
|
||||
|
@ -462,6 +462,7 @@ namespace libtorrent {
|
||||
int seed_rank(aux::session_settings const& s) const;
|
||||
|
||||
void add_piece(piece_index_t piece, char const* data, add_piece_flags_t flags);
|
||||
void add_piece_async(piece_index_t piece, std::vector<char> data, add_piece_flags_t flags);
|
||||
void on_disk_write_complete(storage_error const& error
|
||||
, peer_request const& p);
|
||||
|
||||
|
@ -268,10 +268,7 @@ namespace aux {
|
||||
static constexpr add_piece_flags_t overwrite_existing = 0_bit;
|
||||
|
||||
// This function will write ``data`` to the storage as piece ``piece``,
|
||||
// as if it had been downloaded from a peer. ``data`` is expected to
|
||||
// point to a buffer of as many bytes as the size of the specified piece.
|
||||
// The data in the buffer is copied and passed on to the disk IO thread
|
||||
// to be written at a later point.
|
||||
// as if it had been downloaded from a peer.
|
||||
//
|
||||
// By default, data that's already been downloaded is not overwritten by
|
||||
// this buffer. If you trust this data to be correct (and pass the piece
|
||||
@ -285,7 +282,20 @@ namespace aux {
|
||||
//
|
||||
// Adding pieces while the torrent is being checked (i.e. in
|
||||
// torrent_status::checking_files state) is not supported.
|
||||
//
|
||||
// The overload taking a raw pointer to the data is a blocking call. It
|
||||
// won't return until the libtorrent thread has copied the data into its
|
||||
// disk write buffer. ``data`` is expected to point to a buffer of as
|
||||
// many bytes as the size of the specified piece. See
|
||||
// file_storage::piece_size().
|
||||
//
|
||||
// The data in the buffer is copied and passed on to the disk IO thread
|
||||
// to be written at a later point.
|
||||
//
|
||||
// The overload taking a ``std::vector<char>`` is not blocking, it will
|
||||
// send the buffer to the main thread and return immediately.
|
||||
void add_piece(piece_index_t piece, char const* data, add_piece_flags_t flags = {}) const;
|
||||
void add_piece(piece_index_t piece, std::vector<char> data, add_piece_flags_t flags = {}) const;
|
||||
|
||||
// This function starts an asynchronous read operation of the specified
|
||||
// piece from this torrent. You must have completed the download of the
|
||||
|
@ -1258,12 +1258,33 @@ bool is_downloading_state(int const st)
|
||||
piece_index_t m_piece;
|
||||
};
|
||||
|
||||
void torrent::add_piece_async(piece_index_t const piece
|
||||
, std::vector<char> data, add_piece_flags_t const flags)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
// make sure the piece index is correct
|
||||
if (piece >= torrent_file().end_piece())
|
||||
return;
|
||||
|
||||
// make sure the piece size is correct
|
||||
if (data.size() != std::size_t(m_torrent_file->piece_size(piece)))
|
||||
return;
|
||||
|
||||
add_piece(piece, data.data(), flags);
|
||||
}
|
||||
|
||||
// TODO: 3 there's some duplication between this function and
|
||||
// peer_connection::incoming_piece(). is there a way to merge something?
|
||||
void torrent::add_piece(piece_index_t const piece, char const* data
|
||||
, add_piece_flags_t const flags)
|
||||
{
|
||||
TORRENT_ASSERT(is_single_thread());
|
||||
|
||||
// make sure the piece index is correct
|
||||
if (piece >= torrent_file().end_piece())
|
||||
return;
|
||||
|
||||
int const piece_size = m_torrent_file->piece_size(piece);
|
||||
int const blocks_in_piece = (piece_size + block_size() - 1) / block_size();
|
||||
|
||||
|
@ -121,7 +121,7 @@ namespace libtorrent {
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
(t.get()->*f)(a...);
|
||||
(t.get()->*f)(std::move(a)...);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch (system_error const& e) {
|
||||
ses.alerts().emplace_alert<torrent_error_alert>(torrent_handle(m_torrent)
|
||||
@ -153,7 +153,7 @@ namespace libtorrent {
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
(t.get()->*f)(a...);
|
||||
(t.get()->*f)(std::move(a)...);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
ex = std::current_exception();
|
||||
@ -189,7 +189,7 @@ namespace libtorrent {
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
r = (t.get()->*f)(a...);
|
||||
r = (t.get()->*f)(std::move(a)...);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
} catch (...) {
|
||||
ex = std::current_exception();
|
||||
@ -698,6 +698,12 @@ namespace libtorrent {
|
||||
sync_call(&torrent::add_piece, piece, data, flags);
|
||||
}
|
||||
|
||||
void torrent_handle::add_piece(piece_index_t piece, std::vector<char> data
|
||||
, add_piece_flags_t const flags) const
|
||||
{
|
||||
async_call(&torrent::add_piece_async, piece, std::move(data), flags);
|
||||
}
|
||||
|
||||
void torrent_handle::read_piece(piece_index_t piece) const
|
||||
{
|
||||
async_call(&torrent::read_piece, piece);
|
||||
|
@ -117,7 +117,7 @@ void test_remap_files(storage_mode_t storage_mode = storage_mode_sparse)
|
||||
for (auto const i : fs.piece_range())
|
||||
{
|
||||
std::vector<char> const piece = generate_piece(i, fs.piece_size(i));
|
||||
tor1.add_piece(i, piece.data());
|
||||
tor1.add_piece(i, std::move(piece));
|
||||
}
|
||||
|
||||
// read pieces
|
||||
|
@ -1801,7 +1801,7 @@ TORRENT_TEST(resume_data_have_pieces)
|
||||
atp.save_path = ".";
|
||||
auto h = ses.add_torrent(atp);
|
||||
wait_for_downloading(ses, "");
|
||||
h.add_piece(0_piece, piece_data.data());
|
||||
h.add_piece(0_piece, std::move(piece_data));
|
||||
|
||||
h.save_resume_data();
|
||||
ses.pause();
|
||||
|
@ -875,10 +875,10 @@ TORRENT_TEST(redundant_add_piece)
|
||||
auto h = ses.add_torrent(atp);
|
||||
wait_for_downloading(ses, "");
|
||||
|
||||
h.add_piece(0_piece, piece_data.data());
|
||||
h.add_piece(0_piece, piece_data);
|
||||
h.set_piece_deadline(0_piece, 0, torrent_handle::alert_when_available);
|
||||
h.prioritize_pieces(std::vector<lt::download_priority_t>(std::size_t(ti->num_pieces()), lt::dont_download));
|
||||
h.add_piece(0_piece, piece_data.data());
|
||||
h.add_piece(0_piece, std::move(piece_data));
|
||||
std::this_thread::sleep_for(lt::seconds(2));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user