libtorrent - storage_interface readv explanation -
i have implemented custom storage interface in libtorrent described in section here.
the storage_interface working fine, although can't figure out why readv
called randomly while downloading torrent. view overriden virtual function readv
should called each time call handle->read_piece
in piece_finished_alert
. should read piece read_piece_alert?
the buffer provided in read_piece_alert
without getting notified in readv
.
so question why called randomly , why it's not called on read_piece()
call? storage_interface maybe wrong?
the code looks this:
struct temp_storage : storage_interface { virtual int readv(file::iovec_t const* bufs, int num_bufs , int piece, int offset, int flags, storage_error& ec) { // called on random pieces while downloading larger torrent std::map<int, std::vector<char> >::const_iterator = m_file_data.find(piece); if (i == m_file_data.end()) return 0; int available = i->second.size() - offset; if (available <= 0) return 0; if (available > num_bufs) available = num_bufs; memcpy(&bufs, &i->second[offset], available); return available; } virtual int writev(file::iovec_t const* bufs, int num_bufs , int piece, int offset, int flags, storage_error& ec) { std::vector<char>& data = m_file_data[piece]; if (data.size() < offset + num_bufs) data.resize(offset + num_bufs); std::memcpy(&data[offset], bufs, num_bufs); return num_bufs; } virtual bool has_any_file(storage_error& ec) { return false; } virtual ... virtual ... }
intialized with
storage_interface* temp_storage_constructor(storage_params const& params) { printf("new interface\n"); return new temp_storage(*params.files); } p.storage = &temp_storage_constructor;
the function below sets alerts , invokes read_piece
on each completed piece.
while(true) { std::vector<alert*> alerts; s.pop_alerts(&alerts); (alert* : alerts) { switch (i->type()) { case read_piece_alert::alert_type: { read_piece_alert* p = (read_piece_alert*)i; if (p->ec) { // read_piece failed break; } // piece buffer, size provided without readv // notification after invoking read_piece in piece_finished_alert break; } case piece_finished_alert::alert_type: { piece_finished_alert* p = (piece_finished_alert*)i; p->handle.read_piece(p->piece_index); // once piece finished, read obtain buffer in read_piece_alert. break; } default: break; } } sleep(100); }
i answer own question. arvid said in comments: readv
not invoked because of caching. setting settings_pack::use_read_cache
false invoke readv
always.
Comments
Post a Comment