lt sync 1677
This commit is contained in:
parent
a16eb7625c
commit
b02b71e978
|
@ -87,10 +87,10 @@ namespace
|
|||
|
||||
torrent_handle add_torrent(session& s, torrent_info const& ti
|
||||
, boost::filesystem::path const& save, entry const& resume
|
||||
, bool compact, bool paused)
|
||||
, storage_mode_t storage_mode, bool paused)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.add_torrent(ti, save, resume, compact, paused, default_storage_constructor);
|
||||
return s.add_torrent(ti, save, resume, storage_mode, paused, default_storage_constructor);
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
@ -154,6 +154,17 @@ void bind_session()
|
|||
#endif
|
||||
;
|
||||
|
||||
enum_<storage_mode_t>("storage_mode_t")
|
||||
.value("storage_mode_allocate", storage_mode_allocate)
|
||||
.value("storage_mode_compact", storage_mode_compact)
|
||||
.value("storage_mode_sparse", storage_mode_sparse)
|
||||
;
|
||||
|
||||
enum_<session::options_t>("options_t")
|
||||
.value("none", session::none)
|
||||
.value("delete_files", session::delete_files)
|
||||
;
|
||||
|
||||
class_<session, boost::noncopyable>("session", session_doc, no_init)
|
||||
.def(
|
||||
init<fingerprint>(arg("fingerprint")=fingerprint("LT",0,1,0,0), session_init_doc)
|
||||
|
@ -235,8 +246,6 @@ void bind_session()
|
|||
.def("stop_natpmp", allow_threads(&session::stop_natpmp), session_stop_natpmp_doc)
|
||||
;
|
||||
|
||||
def("supports_sparse_files", &supports_sparse_files);
|
||||
|
||||
register_ptr_to_python<std::auto_ptr<alert> >();
|
||||
}
|
||||
|
||||
|
|
|
@ -252,6 +252,16 @@ namespace libtorrent
|
|||
{ return std::auto_ptr<alert>(new storage_moved_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert
|
||||
{
|
||||
torrent_deleted_alert(torrent_handle const& h, std::string const& msg)
|
||||
: torrent_alert(h, alert::warning, msg)
|
||||
{}
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new torrent_deleted_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT torrent_paused_alert: torrent_alert
|
||||
{
|
||||
torrent_paused_alert(torrent_handle const& h, std::string const& msg)
|
||||
|
|
|
@ -140,7 +140,7 @@ namespace libtorrent
|
|||
checker_impl(session_impl& s): m_ses(s), m_abort(false) {}
|
||||
void operator()();
|
||||
piece_checker_data* find_torrent(const sha1_hash& info_hash);
|
||||
void remove_torrent(sha1_hash const& info_hash);
|
||||
void remove_torrent(sha1_hash const& info_hash, int options);
|
||||
|
||||
#ifndef NDEBUG
|
||||
void check_invariant() const;
|
||||
|
@ -254,7 +254,7 @@ namespace libtorrent
|
|||
boost::intrusive_ptr<torrent_info> ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, storage_constructor_type sc
|
||||
, bool paused
|
||||
, void* userdata);
|
||||
|
@ -265,12 +265,12 @@ namespace libtorrent
|
|||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, storage_constructor_type sc
|
||||
, bool paused
|
||||
, void* userdata);
|
||||
|
||||
void remove_torrent(torrent_handle const& h);
|
||||
void remove_torrent(torrent_handle const& h, int options);
|
||||
|
||||
std::vector<torrent_handle> get_torrents();
|
||||
|
||||
|
@ -371,12 +371,6 @@ namespace libtorrent
|
|||
|
||||
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
|
||||
|
||||
// handles disk io requests asynchronously
|
||||
// peers have pointers into the disk buffer
|
||||
// pool, and must be destructed before this
|
||||
// object.
|
||||
disk_io_thread m_disk_thread;
|
||||
|
||||
// this pool is used to allocate and recycle send
|
||||
// buffers from.
|
||||
boost::pool<> m_send_buffers;
|
||||
|
@ -395,6 +389,12 @@ namespace libtorrent
|
|||
// when they are destructed.
|
||||
file_pool m_files;
|
||||
|
||||
// handles disk io requests asynchronously
|
||||
// peers have pointers into the disk buffer
|
||||
// pool, and must be destructed before this
|
||||
// object.
|
||||
disk_io_thread m_disk_thread;
|
||||
|
||||
// this is a list of half-open tcp connections
|
||||
// (only outgoing connections)
|
||||
// this has to be one of the last
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace libtorrent
|
|||
, hash
|
||||
, move_storage
|
||||
, release_files
|
||||
, delete_files
|
||||
};
|
||||
|
||||
action_t action;
|
||||
|
|
|
@ -176,7 +176,7 @@ namespace libtorrent
|
|||
void set_non_prioritized(bool b)
|
||||
{ m_non_prioritized = b; }
|
||||
|
||||
void fast_reconnect(bool r) { m_fast_reconnect = r; }
|
||||
void fast_reconnect(bool r);
|
||||
bool fast_reconnect() const { return m_fast_reconnect; }
|
||||
|
||||
// this adds an announcement in the announcement queue
|
||||
|
|
|
@ -156,6 +156,8 @@ namespace libtorrent
|
|||
// this is true if the peer is a seed
|
||||
bool seed;
|
||||
|
||||
int fast_reconnects;
|
||||
|
||||
// true if this peer currently is unchoked
|
||||
// because of an optimistic unchoke.
|
||||
// when the optimistic unchoke is moved to
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace libtorrent
|
|||
: m_impl(impl) {}
|
||||
boost::shared_ptr<aux::session_impl> m_impl;
|
||||
};
|
||||
|
||||
|
||||
class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_initializer
|
||||
{
|
||||
public:
|
||||
|
@ -140,7 +140,7 @@ namespace libtorrent
|
|||
torrent_info const& ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, storage_mode_t storage_mode = storage_mode_sparse
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED;
|
||||
|
||||
|
@ -148,7 +148,7 @@ namespace libtorrent
|
|||
boost::intrusive_ptr<torrent_info> ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, storage_mode_t storage_mode = storage_mode_sparse
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor
|
||||
, void* userdata = 0);
|
||||
|
@ -159,7 +159,7 @@ namespace libtorrent
|
|||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, storage_mode_t storage_mode = storage_mode_sparse
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor
|
||||
, void* userdata = 0);
|
||||
|
@ -219,7 +219,13 @@ namespace libtorrent
|
|||
// number of half open connections.
|
||||
int num_connections() const;
|
||||
|
||||
void remove_torrent(const torrent_handle& h);
|
||||
enum options_t
|
||||
{
|
||||
none = 0,
|
||||
delete_files = 1
|
||||
};
|
||||
|
||||
void remove_torrent(const torrent_handle& h, int options = none);
|
||||
|
||||
void set_settings(session_settings const& s);
|
||||
session_settings const& settings();
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace libtorrent
|
|||
, allow_multiple_connections_per_ip(false)
|
||||
, max_failcount(3)
|
||||
, min_reconnect_time(60)
|
||||
, peer_connect_timeout(10)
|
||||
, peer_connect_timeout(7)
|
||||
, ignore_limits_on_local_network(true)
|
||||
, connection_speed(20)
|
||||
, send_redundant_have(false)
|
||||
|
|
|
@ -71,6 +71,13 @@ namespace libtorrent
|
|||
struct file_pool;
|
||||
struct disk_io_job;
|
||||
|
||||
enum storage_mode_t
|
||||
{
|
||||
storage_mode_allocate = 0,
|
||||
storage_mode_sparse,
|
||||
storage_mode_compact
|
||||
};
|
||||
|
||||
#if defined(_WIN32) && defined(UNICODE)
|
||||
|
||||
TORRENT_EXPORT std::wstring safe_convert(std::string const& s);
|
||||
|
@ -144,6 +151,10 @@ namespace libtorrent
|
|||
// writing. This is called when a torrent has finished
|
||||
// downloading.
|
||||
virtual void release_files() = 0;
|
||||
|
||||
// this will close all open files and delete them
|
||||
virtual void delete_files() = 0;
|
||||
|
||||
virtual ~storage_interface() {}
|
||||
};
|
||||
|
||||
|
@ -155,10 +166,6 @@ namespace libtorrent
|
|||
boost::intrusive_ptr<torrent_info const> ti
|
||||
, fs::path const& path, file_pool& fp);
|
||||
|
||||
// returns true if the filesystem the path relies on supports
|
||||
// sparse files or automatic zero filling of files.
|
||||
TORRENT_EXPORT bool supports_sparse_files(fs::path const& p);
|
||||
|
||||
struct disk_io_thread;
|
||||
|
||||
class TORRENT_EXPORT piece_manager
|
||||
|
@ -180,7 +187,8 @@ namespace libtorrent
|
|||
~piece_manager();
|
||||
|
||||
bool check_fastresume(aux::piece_checker_data& d
|
||||
, std::vector<bool>& pieces, int& num_pieces, bool compact_mode);
|
||||
, std::vector<bool>& pieces, int& num_pieces, storage_mode_t storage_mode
|
||||
, std::string& error_msg);
|
||||
std::pair<bool, float> check_files(std::vector<bool>& pieces
|
||||
, int& num_pieces, boost::recursive_mutex& mutex);
|
||||
|
||||
|
@ -191,8 +199,8 @@ namespace libtorrent
|
|||
bool verify_resume_data(entry& rd, std::string& error);
|
||||
|
||||
bool is_allocating() const
|
||||
{ return m_state == state_allocating; }
|
||||
|
||||
{ return m_state == state_expand_pieces; }
|
||||
|
||||
void mark_failed(int index);
|
||||
|
||||
unsigned long piece_crc(
|
||||
|
@ -200,8 +208,9 @@ namespace libtorrent
|
|||
, int block_size
|
||||
, piece_picker::block_info const* bi);
|
||||
|
||||
int slot_for_piece(int piece_index) const;
|
||||
|
||||
int slot_for(int piece) const;
|
||||
int piece_for(int slot) const;
|
||||
|
||||
void async_read(
|
||||
peer_request const& r
|
||||
, boost::function<void(int, disk_io_job const&)> const& handler
|
||||
|
@ -221,6 +230,10 @@ namespace libtorrent
|
|||
boost::function<void(int, disk_io_job const&)> const& handler
|
||||
= boost::function<void(int, disk_io_job const&)>());
|
||||
|
||||
void async_delete_files(
|
||||
boost::function<void(int, disk_io_job const&)> const& handler
|
||||
= boost::function<void(int, disk_io_job const&)>());
|
||||
|
||||
void async_move_storage(fs::path const& p
|
||||
, boost::function<void(int, disk_io_job const&)> const& handler);
|
||||
|
||||
|
@ -228,10 +241,11 @@ namespace libtorrent
|
|||
// slots to the piece that is stored (or
|
||||
// partially stored) there. -2 is the index
|
||||
// of unassigned pieces and -1 is unallocated
|
||||
void export_piece_map(std::vector<int>& pieces) const;
|
||||
void export_piece_map(std::vector<int>& pieces
|
||||
, std::vector<bool> const& have) const;
|
||||
|
||||
bool compact_allocation() const
|
||||
{ return m_compact_mode; }
|
||||
{ return m_storage_mode == storage_mode_compact; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
std::string name() const { return m_info->name(); }
|
||||
|
@ -261,9 +275,11 @@ namespace libtorrent
|
|||
, int offset
|
||||
, int size);
|
||||
|
||||
void switch_to_full_mode();
|
||||
sha1_hash hash_for_piece_impl(int piece);
|
||||
|
||||
void release_files_impl();
|
||||
void release_files_impl() { m_storage->release_files(); }
|
||||
void delete_files_impl() { m_storage->delete_files(); }
|
||||
|
||||
bool move_storage_impl(fs::path const& save_path);
|
||||
|
||||
|
@ -276,19 +292,7 @@ namespace libtorrent
|
|||
#endif
|
||||
boost::scoped_ptr<storage_interface> m_storage;
|
||||
|
||||
// if this is true, pieces are always allocated at the
|
||||
// lowest possible slot index. If it is false, pieces
|
||||
// are always written to their final place immediately
|
||||
bool m_compact_mode;
|
||||
|
||||
// if this is true, pieces that haven't been downloaded
|
||||
// will be filled with zeroes. Not filling with zeroes
|
||||
// will not work in some cases (where a seek cannot pass
|
||||
// the end of the file).
|
||||
bool m_fill_mode;
|
||||
|
||||
// a bitmask representing the pieces we have
|
||||
std::vector<bool> m_have_piece;
|
||||
storage_mode_t m_storage_mode;
|
||||
|
||||
boost::intrusive_ptr<torrent_info const> m_info;
|
||||
|
||||
|
@ -329,10 +333,21 @@ namespace libtorrent
|
|||
state_create_files,
|
||||
// checking the files
|
||||
state_full_check,
|
||||
// allocating files (in non-compact mode)
|
||||
state_allocating
|
||||
// move pieces to their final position
|
||||
state_expand_pieces
|
||||
} m_state;
|
||||
int m_current_slot;
|
||||
// used during check. If any piece is found
|
||||
// that is not in its final position, this
|
||||
// is set to true
|
||||
bool m_out_of_place;
|
||||
// used to move pieces while expanding
|
||||
// the storage from compact allocation
|
||||
// to full allocation
|
||||
std::vector<char> m_scratch_buffer;
|
||||
std::vector<char> m_scratch_buffer2;
|
||||
// the piece that is in the scratch buffer
|
||||
int m_scratch_piece;
|
||||
|
||||
// this is saved in case we need to instantiate a new
|
||||
// storage (osed when remapping files)
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace libtorrent
|
|||
, boost::intrusive_ptr<torrent_info> tf
|
||||
, fs::path const& save_path
|
||||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, storage_mode_t m_storage_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
|
@ -116,7 +116,7 @@ namespace libtorrent
|
|||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, storage_mode_t m_storage_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
|
@ -177,6 +177,8 @@ namespace libtorrent
|
|||
void resume();
|
||||
bool is_paused() const { return m_paused; }
|
||||
|
||||
void delete_files();
|
||||
|
||||
// ============ start deprecation =============
|
||||
void filter_piece(int index, bool filter);
|
||||
void filter_pieces(std::vector<bool> const& bitmask);
|
||||
|
@ -550,6 +552,7 @@ namespace libtorrent
|
|||
|
||||
private:
|
||||
|
||||
void on_files_deleted(int ret, disk_io_job const& j);
|
||||
void on_files_released(int ret, disk_io_job const& j);
|
||||
void on_torrent_paused(int ret, disk_io_job const& j);
|
||||
void on_storage_moved(int ret, disk_io_job const& j);
|
||||
|
@ -751,7 +754,7 @@ namespace libtorrent
|
|||
fs::path m_save_path;
|
||||
|
||||
// determines the storage state for this torrent.
|
||||
const bool m_compact_mode;
|
||||
storage_mode_t m_storage_mode;
|
||||
|
||||
// defaults to 16 kiB, but can be set by the user
|
||||
// when creating the torrent
|
||||
|
|
|
@ -52,6 +52,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -106,7 +107,7 @@ namespace libtorrent
|
|||
, num_connections(0)
|
||||
, uploads_limit(0)
|
||||
, connections_limit(0)
|
||||
, compact_mode(false)
|
||||
, storage_mode(storage_mode_sparse)
|
||||
{}
|
||||
|
||||
enum state_t
|
||||
|
@ -216,7 +217,7 @@ namespace libtorrent
|
|||
|
||||
// true if the torrent is saved in compact mode
|
||||
// false if it is saved in full allocation mode
|
||||
bool compact_mode;
|
||||
storage_mode_t storage_mode;
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT block_info
|
||||
|
|
|
@ -204,7 +204,6 @@ namespace libtorrent
|
|||
|
||||
// if this fails, we need to reconnect
|
||||
// fast.
|
||||
pi->connected = time_now() - seconds(m_ses.settings().min_reconnect_time);
|
||||
fast_reconnect(true);
|
||||
|
||||
write_pe1_2_dhkey();
|
||||
|
@ -802,9 +801,9 @@ namespace libtorrent
|
|||
{
|
||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||
TORRENT_ASSERT(t);
|
||||
while (!request_queue().empty())
|
||||
while (!download_queue().empty())
|
||||
{
|
||||
piece_block const& b = request_queue().front();
|
||||
piece_block const& b = download_queue().front();
|
||||
peer_request r;
|
||||
r.piece = b.piece_index;
|
||||
r.start = b.block_index * t->block_size();
|
||||
|
|
|
@ -125,6 +125,7 @@ namespace libtorrent
|
|||
, boost::function<void(int, disk_io_job const&)> const& f)
|
||||
{
|
||||
TORRENT_ASSERT(!j.callback);
|
||||
TORRENT_ASSERT(j.storage);
|
||||
boost::mutex::scoped_lock l(m_mutex);
|
||||
|
||||
std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin();
|
||||
|
@ -220,6 +221,7 @@ namespace libtorrent
|
|||
bool free_buffer = true;
|
||||
try
|
||||
{
|
||||
TORRENT_ASSERT(j.storage);
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
ptime start = time_now();
|
||||
#endif
|
||||
|
@ -288,6 +290,12 @@ namespace libtorrent
|
|||
#endif
|
||||
j.storage->release_files_impl();
|
||||
break;
|
||||
case disk_io_job::delete_files:
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " delete" << std::endl;
|
||||
#endif
|
||||
j.storage->delete_files_impl();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
|
|
@ -394,6 +394,16 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
void peer_connection::fast_reconnect(bool r)
|
||||
{
|
||||
if (peer_info_struct() && peer_info_struct()->fast_reconnects > 1) return;
|
||||
m_fast_reconnect = r;
|
||||
peer_info_struct()->connected = time_now()
|
||||
- seconds(m_ses.settings().min_reconnect_time
|
||||
* m_ses.settings().max_failcount);
|
||||
if (peer_info_struct()) ++peer_info_struct()->fast_reconnects;
|
||||
}
|
||||
|
||||
void peer_connection::announce_piece(int index)
|
||||
{
|
||||
// dont announce during handshake
|
||||
|
@ -643,27 +653,23 @@ namespace libtorrent
|
|||
m_peer_choked = true;
|
||||
t->get_policy().choked(*this);
|
||||
|
||||
if (!t->is_seed())
|
||||
if (peer_info_struct() == 0 || !peer_info_struct()->on_parole)
|
||||
{
|
||||
piece_picker& p = t->picker();
|
||||
// remove all pieces from this peers download queue and
|
||||
// remove the 'downloading' flag from piece_picker.
|
||||
for (std::deque<piece_block>::iterator i = m_download_queue.begin();
|
||||
i != m_download_queue.end(); ++i)
|
||||
// if the peer is not in parole mode, clear the queued
|
||||
// up block requests
|
||||
if (!t->is_seed())
|
||||
{
|
||||
p.abort_download(*i);
|
||||
}
|
||||
for (std::deque<piece_block>::const_iterator i = m_request_queue.begin()
|
||||
, end(m_request_queue.end()); i != end; ++i)
|
||||
{
|
||||
// since this piece was skipped, clear it and allow it to
|
||||
// be requested from other peers
|
||||
p.abort_download(*i);
|
||||
piece_picker& p = t->picker();
|
||||
for (std::deque<piece_block>::const_iterator i = m_request_queue.begin()
|
||||
, end(m_request_queue.end()); i != end; ++i)
|
||||
{
|
||||
// since this piece was skipped, clear it and allow it to
|
||||
// be requested from other peers
|
||||
p.abort_download(*i);
|
||||
}
|
||||
}
|
||||
m_request_queue.clear();
|
||||
}
|
||||
|
||||
m_download_queue.clear();
|
||||
m_request_queue.clear();
|
||||
}
|
||||
|
||||
bool match_request(peer_request const& r, piece_block const& b, int block_size)
|
||||
|
@ -707,23 +713,17 @@ namespace libtorrent
|
|||
{
|
||||
b = *i;
|
||||
m_download_queue.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = std::find_if(m_request_queue.begin(), m_request_queue.end()
|
||||
, bind(match_request, boost::cref(r), _1, t->block_size()));
|
||||
|
||||
if (i != m_request_queue.end())
|
||||
|
||||
// if the peer is in parole mode, keep the request
|
||||
if (peer_info_struct() && peer_info_struct()->on_parole)
|
||||
{
|
||||
b = *i;
|
||||
m_request_queue.erase(i);
|
||||
m_request_queue.push_front(b);
|
||||
}
|
||||
else if (!t->is_seed())
|
||||
{
|
||||
piece_picker& p = t->picker();
|
||||
p.abort_download(b);
|
||||
}
|
||||
}
|
||||
|
||||
if (b.piece_index != -1 && !t->is_seed())
|
||||
{
|
||||
piece_picker& p = t->picker();
|
||||
p.abort_download(b);
|
||||
}
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
else
|
||||
|
@ -1932,7 +1932,6 @@ namespace libtorrent
|
|||
|
||||
void peer_connection::timed_out()
|
||||
{
|
||||
if (m_peer_info) ++m_peer_info->failcount;
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_ses.m_logger) << "CONNECTION TIMED OUT: " << m_remote.address().to_string()
|
||||
<< "\n";
|
||||
|
|
|
@ -1732,7 +1732,6 @@ namespace libtorrent
|
|||
++i->writing;
|
||||
info.state = block_info::state_writing;
|
||||
if (info.num_peers > 0) --info.num_peers;
|
||||
TORRENT_ASSERT(info.num_peers >= 0);
|
||||
|
||||
if (i->requested == 0)
|
||||
{
|
||||
|
@ -1855,7 +1854,6 @@ namespace libtorrent
|
|||
|
||||
block_info& info = i->info[block.block_index];
|
||||
--info.num_peers;
|
||||
TORRENT_ASSERT(info.num_peers >= 0);
|
||||
if (info.num_peers > 0) return;
|
||||
|
||||
if (i->info[block.block_index].state == block_info::state_finished
|
||||
|
|
|
@ -986,7 +986,8 @@ namespace libtorrent
|
|||
i->second.prev_amount_upload = 0;
|
||||
i->second.connection = &c;
|
||||
TORRENT_ASSERT(i->second.connection);
|
||||
i->second.connected = time_now();
|
||||
if (!c.fast_reconnect())
|
||||
i->second.connected = time_now();
|
||||
// m_last_optimistic_disconnect = time_now();
|
||||
}
|
||||
|
||||
|
@ -1045,10 +1046,10 @@ namespace libtorrent
|
|||
|
||||
// we don't have any info about this peer.
|
||||
// add a new entry
|
||||
peer p(remote, peer::connectable, src);
|
||||
i = m_peers.insert(std::make_pair(remote.address(), p));
|
||||
i = m_peers.insert(std::make_pair(remote.address()
|
||||
, peer(remote, peer::connectable, src)));
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
if (flags & 0x01) p.pe_support = true;
|
||||
if (flags & 0x01) i->second.pe_support = true;
|
||||
#endif
|
||||
if (flags & 0x02) i->second.seed = true;
|
||||
|
||||
|
@ -1503,6 +1504,7 @@ namespace libtorrent
|
|||
, failcount(0)
|
||||
, hashfails(0)
|
||||
, seed(false)
|
||||
, fast_reconnects(0)
|
||||
, optimistically_unchoked(false)
|
||||
, last_optimistically_unchoked(min_time())
|
||||
, connected(min_time())
|
||||
|
|
|
@ -186,28 +186,28 @@ namespace libtorrent
|
|||
torrent_info const& ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, bool paused
|
||||
, storage_constructor_type sc)
|
||||
{
|
||||
TORRENT_ASSERT(!ti.m_half_metadata);
|
||||
boost::intrusive_ptr<torrent_info> tip(new torrent_info(ti));
|
||||
return m_impl->add_torrent(tip, save_path, resume_data
|
||||
, compact_mode, sc, paused, 0);
|
||||
, storage_mode, sc, paused, 0);
|
||||
}
|
||||
|
||||
torrent_handle session::add_torrent(
|
||||
boost::intrusive_ptr<torrent_info> ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, bool paused
|
||||
, storage_constructor_type sc
|
||||
, void* userdata)
|
||||
{
|
||||
TORRENT_ASSERT(!ti->m_half_metadata);
|
||||
return m_impl->add_torrent(ti, save_path, resume_data
|
||||
, compact_mode, sc, paused, userdata);
|
||||
, storage_mode, sc, paused, userdata);
|
||||
}
|
||||
|
||||
torrent_handle session::add_torrent(
|
||||
|
@ -216,18 +216,18 @@ namespace libtorrent
|
|||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, entry const& e
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, bool paused
|
||||
, storage_constructor_type sc
|
||||
, void* userdata)
|
||||
{
|
||||
return m_impl->add_torrent(tracker_url, info_hash, name, save_path, e
|
||||
, compact_mode, sc, paused, userdata);
|
||||
, storage_mode, sc, paused, userdata);
|
||||
}
|
||||
|
||||
void session::remove_torrent(const torrent_handle& h)
|
||||
void session::remove_torrent(const torrent_handle& h, int options)
|
||||
{
|
||||
m_impl->remove_torrent(h);
|
||||
m_impl->remove_torrent(h, options);
|
||||
}
|
||||
|
||||
bool session::listen_on(
|
||||
|
|
|
@ -189,9 +189,11 @@ namespace detail
|
|||
t->parse_resume_data(t->resume_data, t->torrent_ptr->torrent_file()
|
||||
, error_msg);
|
||||
|
||||
// lock the session to add the new torrent
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
|
||||
if (!error_msg.empty() && m_ses.m_alerts.should_post(alert::warning))
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.m_alerts.post_alert(fastresume_rejected_alert(
|
||||
t->torrent_ptr->get_handle()
|
||||
, error_msg));
|
||||
|
@ -202,8 +204,6 @@ namespace detail
|
|||
#endif
|
||||
}
|
||||
|
||||
// lock the session to add the new torrent
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
mutex::scoped_lock l2(m_mutex);
|
||||
|
||||
if (m_torrents.empty() || m_torrents.front() != t)
|
||||
|
@ -328,7 +328,7 @@ namespace detail
|
|||
boost::tie(finished, progress) = processing->torrent_ptr->check_files();
|
||||
|
||||
{
|
||||
mutex::scoped_lock l(m_mutex);
|
||||
mutex::scoped_lock l2(m_mutex);
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -340,9 +340,9 @@ namespace detail
|
|||
m_processing.pop_front();
|
||||
|
||||
// make sure the lock order is correct
|
||||
l.unlock();
|
||||
l2.unlock();
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
l.lock();
|
||||
l2.lock();
|
||||
processing->torrent_ptr->abort();
|
||||
|
||||
processing.reset();
|
||||
|
@ -481,7 +481,7 @@ namespace detail
|
|||
return 0;
|
||||
}
|
||||
|
||||
void checker_impl::remove_torrent(sha1_hash const& info_hash)
|
||||
void checker_impl::remove_torrent(sha1_hash const& info_hash, int options)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
for (std::deque<boost::shared_ptr<piece_checker_data> >::iterator i
|
||||
|
@ -490,6 +490,8 @@ namespace detail
|
|||
if ((*i)->info_hash == info_hash)
|
||||
{
|
||||
TORRENT_ASSERT((*i)->processing == false);
|
||||
if (options & session::delete_files)
|
||||
(*i)->torrent_ptr->delete_files();
|
||||
m_torrents.erase(i);
|
||||
return;
|
||||
}
|
||||
|
@ -500,6 +502,8 @@ namespace detail
|
|||
if ((*i)->info_hash == info_hash)
|
||||
{
|
||||
TORRENT_ASSERT((*i)->processing == false);
|
||||
if (options & session::delete_files)
|
||||
(*i)->torrent_ptr->delete_files();
|
||||
m_processing.erase(i);
|
||||
return;
|
||||
}
|
||||
|
@ -565,8 +569,19 @@ namespace detail
|
|||
, m_checker_impl(*this)
|
||||
{
|
||||
#ifdef WIN32
|
||||
// windows XP has a limit of 10 simultaneous connections
|
||||
m_half_open.limit(8);
|
||||
// windows XP has a limit on the number of
|
||||
// simultaneous half-open TCP connections
|
||||
DWORD windows_version = ::GetVersion();
|
||||
if ((windows_version & 0xff) >= 6)
|
||||
{
|
||||
// on vista the limit is 5 (in home edition)
|
||||
m_half_open.limit(4);
|
||||
}
|
||||
else
|
||||
{
|
||||
// on XP SP2 it's 10
|
||||
m_half_open.limit(8);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_bandwidth_manager[peer_connection::download_channel] = &m_download_channel;
|
||||
|
@ -1623,7 +1638,7 @@ namespace detail
|
|||
boost::intrusive_ptr<torrent_info> ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, storage_constructor_type sc
|
||||
, bool paused
|
||||
, void* userdata)
|
||||
|
@ -1655,7 +1670,7 @@ namespace detail
|
|||
// the thread
|
||||
boost::shared_ptr<torrent> torrent_ptr(
|
||||
new torrent(*this, m_checker_impl, ti, save_path
|
||||
, m_listen_interface, compact_mode, 16 * 1024
|
||||
, m_listen_interface, storage_mode, 16 * 1024
|
||||
, sc, paused));
|
||||
torrent_ptr->start();
|
||||
|
||||
|
@ -1701,7 +1716,7 @@ namespace detail
|
|||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, entry const&
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, storage_constructor_type sc
|
||||
, bool paused
|
||||
, void* userdata)
|
||||
|
@ -1735,7 +1750,7 @@ namespace detail
|
|||
// the thread
|
||||
boost::shared_ptr<torrent> torrent_ptr(
|
||||
new torrent(*this, m_checker_impl, tracker_url, info_hash, name
|
||||
, save_path, m_listen_interface, compact_mode, 16 * 1024
|
||||
, save_path, m_listen_interface, storage_mode, 16 * 1024
|
||||
, sc, paused));
|
||||
torrent_ptr->start();
|
||||
|
||||
|
@ -1754,7 +1769,7 @@ namespace detail
|
|||
return torrent_handle(this, &m_checker_impl, info_hash);
|
||||
}
|
||||
|
||||
void session_impl::remove_torrent(const torrent_handle& h)
|
||||
void session_impl::remove_torrent(const torrent_handle& h, int options)
|
||||
{
|
||||
if (h.m_ses != this) return;
|
||||
TORRENT_ASSERT(h.m_chk == &m_checker_impl || h.m_chk == 0);
|
||||
|
@ -1769,6 +1784,8 @@ namespace detail
|
|||
if (i != m_torrents.end())
|
||||
{
|
||||
torrent& t = *i->second;
|
||||
if (options & session::delete_files)
|
||||
t.delete_files();
|
||||
t.abort();
|
||||
|
||||
if ((!t.is_paused() || t.should_request())
|
||||
|
@ -1815,7 +1832,7 @@ namespace detail
|
|||
if (d != 0)
|
||||
{
|
||||
if (d->processing) d->abort = true;
|
||||
else m_checker_impl.remove_torrent(h.m_info_hash);
|
||||
else m_checker_impl.remove_torrent(h.m_info_hash, options);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -154,7 +154,7 @@ namespace libtorrent
|
|||
, boost::intrusive_ptr<torrent_info> tf
|
||||
, fs::path const& save_path
|
||||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc
|
||||
, bool paused)
|
||||
|
@ -195,7 +195,7 @@ namespace libtorrent
|
|||
, m_total_redundant_bytes(0)
|
||||
, m_net_interface(net_interface.address(), 0)
|
||||
, m_save_path(complete(save_path))
|
||||
, m_compact_mode(compact_mode)
|
||||
, m_storage_mode(storage_mode)
|
||||
, m_default_block_size(block_size)
|
||||
, m_connections_initialized(true)
|
||||
, m_settings(ses.settings())
|
||||
|
@ -215,7 +215,7 @@ namespace libtorrent
|
|||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, storage_mode_t storage_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc
|
||||
, bool paused)
|
||||
|
@ -255,7 +255,7 @@ namespace libtorrent
|
|||
, m_total_redundant_bytes(0)
|
||||
, m_net_interface(net_interface.address(), 0)
|
||||
, m_save_path(complete(save_path))
|
||||
, m_compact_mode(compact_mode)
|
||||
, m_storage_mode(storage_mode)
|
||||
, m_default_block_size(block_size)
|
||||
, m_connections_initialized(false)
|
||||
, m_settings(ses.settings())
|
||||
|
@ -1032,6 +1032,16 @@ namespace libtorrent
|
|||
m_announce_timer.cancel();
|
||||
}
|
||||
|
||||
void torrent::on_files_deleted(int ret, disk_io_job const& j)
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
|
||||
if (alerts().should_post(alert::warning))
|
||||
{
|
||||
alerts().post_alert(torrent_deleted_alert(get_handle(), "files deleted"));
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::on_files_released(int ret, disk_io_job const& j)
|
||||
{
|
||||
/*
|
||||
|
@ -1668,8 +1678,6 @@ namespace libtorrent
|
|||
|
||||
try
|
||||
{
|
||||
TORRENT_ASSERT(m_connections.find(a) == m_connections.end());
|
||||
|
||||
// add the newly connected peer to this torrent's peer list
|
||||
TORRENT_ASSERT(m_connections.find(a) == m_connections.end());
|
||||
m_connections.insert(
|
||||
|
@ -1883,10 +1891,13 @@ namespace libtorrent
|
|||
std::make_pair(a, boost::get_pointer(c)));
|
||||
m_ses.m_connections.insert(std::make_pair(s, c));
|
||||
|
||||
int timeout = settings().peer_connect_timeout;
|
||||
if (peerinfo) timeout += 3 * peerinfo->failcount;
|
||||
|
||||
m_ses.m_half_open.enqueue(
|
||||
bind(&peer_connection::connect, c, _1)
|
||||
, bind(&peer_connection::timed_out, c)
|
||||
, seconds(settings().peer_connect_timeout));
|
||||
, seconds(timeout));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -2215,10 +2226,22 @@ namespace libtorrent
|
|||
bool done = true;
|
||||
try
|
||||
{
|
||||
std::string error_msg;
|
||||
TORRENT_ASSERT(m_storage);
|
||||
TORRENT_ASSERT(m_owning_storage.get());
|
||||
done = m_storage->check_fastresume(data, m_have_pieces, m_num_pieces
|
||||
, m_compact_mode);
|
||||
, m_storage_mode, error_msg);
|
||||
|
||||
if (!error_msg.empty() && m_ses.m_alerts.should_post(alert::warning))
|
||||
{
|
||||
m_ses.m_alerts.post_alert(fastresume_rejected_alert(
|
||||
get_handle(), error_msg));
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
(*m_ses.m_logger) << "fastresume data for "
|
||||
<< torrent_file().name() << " rejected: "
|
||||
<< error_msg << "\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
|
@ -2378,8 +2401,6 @@ namespace libtorrent
|
|||
|
||||
piece_manager& torrent::filesystem()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
TORRENT_ASSERT(m_owning_storage.get());
|
||||
return *m_owning_storage;
|
||||
}
|
||||
|
@ -2537,6 +2558,29 @@ namespace libtorrent
|
|||
return limit;
|
||||
}
|
||||
|
||||
void torrent::delete_files()
|
||||
{
|
||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||
for (peer_iterator i = m_connections.begin();
|
||||
i != m_connections.end(); ++i)
|
||||
{
|
||||
(*i->second->m_logger) << "*** DELETING FILES IN TORRENT\n";
|
||||
}
|
||||
#endif
|
||||
|
||||
disconnect_all();
|
||||
m_paused = true;
|
||||
// tell the tracker that we stopped
|
||||
m_event = tracker_request::stopped;
|
||||
|
||||
if (m_owning_storage.get())
|
||||
{
|
||||
TORRENT_ASSERT(m_storage);
|
||||
m_storage->async_delete_files(
|
||||
bind(&torrent::on_files_deleted, shared_from_this(), _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
void torrent::pause()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
@ -2768,7 +2812,7 @@ namespace libtorrent
|
|||
!boost::bind(&peer_connection::is_connecting
|
||||
, boost::bind(&std::map<tcp::endpoint,peer_connection*>::value_type::second, _1)));
|
||||
|
||||
st.compact_mode = m_compact_mode;
|
||||
st.storage_mode = m_storage_mode;
|
||||
|
||||
st.num_complete = m_complete;
|
||||
st.num_incomplete = m_incomplete;
|
||||
|
|
|
@ -661,7 +661,7 @@ namespace libtorrent
|
|||
|
||||
if (!t->valid_metadata()) return entry();
|
||||
|
||||
t->filesystem().export_piece_map(piece_index);
|
||||
std::vector<bool> have_pieces = t->pieces();
|
||||
|
||||
entry ret(entry::dictionary_t);
|
||||
|
||||
|
@ -673,10 +673,6 @@ namespace libtorrent
|
|||
const sha1_hash& info_hash = t->torrent_file().info_hash();
|
||||
ret["info-hash"] = std::string((char*)info_hash.begin(), (char*)info_hash.end());
|
||||
|
||||
ret["slots"] = entry(entry::list_t);
|
||||
entry::list_type& slots = ret["slots"].list();
|
||||
std::copy(piece_index.begin(), piece_index.end(), std::back_inserter(slots));
|
||||
|
||||
// blocks per piece
|
||||
int num_blocks_per_piece =
|
||||
static_cast<int>(t->torrent_file().piece_length()) / t->block_size();
|
||||
|
@ -706,6 +702,8 @@ namespace libtorrent
|
|||
// the unfinished piece's index
|
||||
piece_struct["piece"] = i->index;
|
||||
|
||||
have_pieces[i->index] = true;
|
||||
|
||||
std::string bitmask;
|
||||
const int num_bitmask_bytes
|
||||
= (std::max)(num_blocks_per_piece / 8, 1);
|
||||
|
@ -722,10 +720,10 @@ namespace libtorrent
|
|||
}
|
||||
piece_struct["bitmask"] = bitmask;
|
||||
|
||||
TORRENT_ASSERT(t->filesystem().slot_for_piece(i->index) >= 0);
|
||||
TORRENT_ASSERT(t->filesystem().slot_for(i->index) >= 0);
|
||||
unsigned long adler
|
||||
= t->filesystem().piece_crc(
|
||||
t->filesystem().slot_for_piece(i->index)
|
||||
t->filesystem().slot_for(i->index)
|
||||
, t->block_size()
|
||||
, i->info);
|
||||
|
||||
|
@ -735,6 +733,11 @@ namespace libtorrent
|
|||
up.push_back(piece_struct);
|
||||
}
|
||||
}
|
||||
|
||||
t->filesystem().export_piece_map(piece_index, have_pieces);
|
||||
entry::list_type& slots = ret["slots"].list();
|
||||
std::copy(piece_index.begin(), piece_index.end(), std::back_inserter(slots));
|
||||
|
||||
// write local peers
|
||||
|
||||
entry::list_type& peer_list = ret["peers"].list();
|
||||
|
|
Loading…
Reference in New Issue