| alert_types.hpp | | alert_types.hpp | |
| | | | |
| skipping to change at line 43 | | skipping to change at line 43 | |
| #ifndef TORRENT_ALERT_TYPES_HPP_INCLUDED | | #ifndef TORRENT_ALERT_TYPES_HPP_INCLUDED | |
| #define TORRENT_ALERT_TYPES_HPP_INCLUDED | | #define TORRENT_ALERT_TYPES_HPP_INCLUDED | |
| | | | |
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/peer_connection.hpp" | | #include "libtorrent/peer_connection.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/identify_client.hpp" | | #include "libtorrent/identify_client.hpp" | |
|
| | | #include "libtorrent/stat.hpp" | |
| #include <boost/lexical_cast.hpp> | | | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| struct TORRENT_EXPORT torrent_alert: alert | | struct TORRENT_EXPORT torrent_alert: alert | |
| { | | { | |
| torrent_alert(torrent_handle const& h) | | torrent_alert(torrent_handle const& h) | |
| : handle(h) | | : handle(h) | |
| {} | | {} | |
| | | | |
| virtual std::string message() const | | virtual std::string message() const | |
| | | | |
| skipping to change at line 100 | | skipping to change at line 99 | |
| const static int static_category = alert::tracker_notificati
on; | | const static int static_category = alert::tracker_notificati
on; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " (" + url + ")"; | | return torrent_alert::message() + " (" + url + ")"; | |
| } | | } | |
| | | | |
| std::string url; | | std::string url; | |
| }; | | }; | |
| | | | |
|
| | | struct TORRENT_EXPORT read_piece_alert: torrent_alert | |
| | | { | |
| | | read_piece_alert(torrent_handle const& h | |
| | | , int p, boost::shared_array<char> d, int s) | |
| | | : torrent_alert(h) | |
| | | , buffer(d) | |
| | | , piece(p) | |
| | | , size(s) | |
| | | {} | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new read_piece_alert(*this)); | |
| | | } | |
| | | const static int static_category = alert::storage_notificati | |
| | | on; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual char const* what() const { return "read piece"; } | |
| | | virtual std::string message() const | |
| | | { | |
| | | char msg[200]; | |
| | | snprintf(msg, sizeof(msg), "%s: piece %s %u", torren | |
| | | t_alert::message().c_str() | |
| | | , buffer ? "successful" : "failed", piece); | |
| | | return msg; | |
| | | } | |
| | | | |
| | | boost::shared_array<char> buffer; | |
| | | int piece; | |
| | | int size; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT file_completed_alert: torrent_alert | |
| | | { | |
| | | file_completed_alert(torrent_handle const& h | |
| | | , int index_) | |
| | | : torrent_alert(h) | |
| | | , index(index_) | |
| | | {} | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new file_completed_alert(*this | |
| | | )); } | |
| | | const static int static_category = alert::progress_notificat | |
| | | ion; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual char const* what() const { return "file completed"; | |
| | | } | |
| | | virtual std::string message() const | |
| | | { | |
| | | char msg[200]; | |
| | | snprintf(msg, sizeof(msg), "%s: file %d finished dow | |
| | | nloading" | |
| | | , torrent_alert::message().c_str(), index); | |
| | | return msg; | |
| | | } | |
| | | | |
| | | int index; | |
| | | }; | |
| | | | |
| struct TORRENT_EXPORT file_renamed_alert: torrent_alert | | struct TORRENT_EXPORT file_renamed_alert: torrent_alert | |
| { | | { | |
| file_renamed_alert(torrent_handle const& h | | file_renamed_alert(torrent_handle const& h | |
| , std::string const& name_ | | , std::string const& name_ | |
| , int index_) | | , int index_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , name(name_) | | , name(name_) | |
| , index(index_) | | , index(index_) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new file_renamed_alert(*this))
; } | | { return std::auto_ptr<alert>(new file_renamed_alert(*this))
; } | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual char const* what() const { return "file renamed"; } | | virtual char const* what() const { return "file renamed"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char msg[200 + NAME_MAX]; | |
| ret << torrent_alert::message() << ": file " | | snprintf(msg, sizeof(msg), "%s: file %d renamed to % | |
| << index << " renamed to " << name; | | s", torrent_alert::message().c_str() | |
| return ret.str(); | | , index, name.c_str()); | |
| | | return msg; | |
| } | | } | |
| | | | |
| std::string name; | | std::string name; | |
| int index; | | int index; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert | | struct TORRENT_EXPORT file_rename_failed_alert: torrent_alert | |
| { | | { | |
| file_rename_failed_alert(torrent_handle const& h | | file_rename_failed_alert(torrent_handle const& h | |
|
| , std::string const& msg_ | | , int index_ | |
| , int index_) | | , error_code ec_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
|
| , msg(msg_) | | | |
| , index(index_) | | , index(index_) | |
|
| | | , error(ec_) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new file_rename_failed_alert(*
this)); } | | { return std::auto_ptr<alert>(new file_rename_failed_alert(*
this)); } | |
| | | | |
| virtual char const* what() const { return "file rename faile
d"; } | | virtual char const* what() const { return "file rename faile
d"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200 + NAME_MAX]; | |
| ret << torrent_alert::message() << ": failed to rena | | snprintf(ret, sizeof(ret), "%s: failed to rename fil | |
| me file " | | e %d: %s" | |
| << index << ": " << msg; | | , torrent_alert::message().c_str(), index, e | |
| return ret.str(); | | rror.message().c_str()); | |
| | | return ret; | |
| } | | } | |
| | | | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| | | | |
|
| std::string msg; | | | |
| int index; | | int index; | |
|
| | | error_code error; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT performance_alert: torrent_alert | | struct TORRENT_EXPORT performance_alert: torrent_alert | |
| { | | { | |
| enum performance_warning_t | | enum performance_warning_t | |
| { | | { | |
| outstanding_disk_buffer_limit_reached, | | outstanding_disk_buffer_limit_reached, | |
|
| outstanding_request_limit_reached | | outstanding_request_limit_reached, | |
| | | upload_limit_too_low, | |
| | | download_limit_too_low, | |
| | | send_buffer_watermark_too_low, | |
| | | | |
| | | num_warnings | |
| }; | | }; | |
| | | | |
| performance_alert(torrent_handle const& h | | performance_alert(torrent_handle const& h | |
| , performance_warning_t w) | | , performance_warning_t w) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , warning_code(w) | | , warning_code(w) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new performance_alert(*this));
} | | { return std::auto_ptr<alert>(new performance_alert(*this));
} | |
| | | | |
| virtual char const* what() const { return "performance warni
ng"; } | | virtual char const* what() const { return "performance warni
ng"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| static char const* warning_str[] = | | static char const* warning_str[] = | |
| { | | { | |
| "max outstanding disk writes reached", | | "max outstanding disk writes reached", | |
| "max outstanding piece requests reached", | | "max outstanding piece requests reached", | |
|
| | | "upload limit too low (download rate will su | |
| | | ffer)", | |
| | | "download limit too low (upload rate will su | |
| | | ffer)", | |
| | | "send buffer watermark too low (upload rate | |
| | | will suffer)" | |
| }; | | }; | |
| | | | |
| return torrent_alert::message() + ": performance war
ning: " | | return torrent_alert::message() + ": performance war
ning: " | |
| + warning_str[warning_code]; | | + warning_str[warning_code]; | |
| } | | } | |
| | | | |
| const static int static_category = alert::performance_warnin
g; | | const static int static_category = alert::performance_warnin
g; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| | | | |
| performance_warning_t warning_code; | | performance_warning_t warning_code; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT state_changed_alert: torrent_alert | | struct TORRENT_EXPORT state_changed_alert: torrent_alert | |
| { | | { | |
| state_changed_alert(torrent_handle const& h | | state_changed_alert(torrent_handle const& h | |
|
| , torrent_status::state_t const& state_) | | , torrent_status::state_t state_ | |
| | | , torrent_status::state_t prev_state_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , state(state_) | | , state(state_) | |
|
| | | , prev_state(prev_state_) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new state_changed_alert(*this)
); } | | { return std::auto_ptr<alert>(new state_changed_alert(*this)
); } | |
| | | | |
| virtual char const* what() const { return "torrent state cha
nged"; } | | virtual char const* what() const { return "torrent state cha
nged"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| static char const* state_str[] = | | static char const* state_str[] = | |
| {"checking (q)", "checking", "dl metadata" | | {"checking (q)", "checking", "dl metadata" | |
| | | | |
| skipping to change at line 219 | | skipping to change at line 280 | |
| , "checking (r)"}; | | , "checking (r)"}; | |
| | | | |
| return torrent_alert::message() + ": state changed t
o: " | | return torrent_alert::message() + ": state changed t
o: " | |
| + state_str[state]; | | + state_str[state]; | |
| } | | } | |
| | | | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| | | | |
| torrent_status::state_t state; | | torrent_status::state_t state; | |
|
| | | torrent_status::state_t prev_state; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_error_alert: tracker_alert | | struct TORRENT_EXPORT tracker_error_alert: tracker_alert | |
| { | | { | |
| tracker_error_alert(torrent_handle const& h | | tracker_error_alert(torrent_handle const& h | |
| , int times | | , int times | |
| , int status | | , int status | |
| , std::string const& url_ | | , std::string const& url_ | |
|
| | | , error_code const& e) | |
| | | : tracker_alert(h, url_) | |
| | | , times_in_row(times) | |
| | | , status_code(status) | |
| | | , msg(e.message()) | |
| | | { | |
| | | TORRENT_ASSERT(!url.empty()); | |
| | | } | |
| | | | |
| | | tracker_error_alert(torrent_handle const& h | |
| | | , int times | |
| | | , int status | |
| | | , std::string const& url_ | |
| , std::string const& msg_) | | , std::string const& msg_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , times_in_row(times) | | , times_in_row(times) | |
| , status_code(status) | | , status_code(status) | |
| , msg(msg_) | | , msg(msg_) | |
|
| { TORRENT_ASSERT(!url.empty()); } | | { | |
| | | TORRENT_ASSERT(!url.empty()); | |
| | | } | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new tracker_error_alert(*this)
); } | | { return std::auto_ptr<alert>(new tracker_error_alert(*this)
); } | |
| const static int static_category = alert::tracker_notificati
on | alert::error_notification; | | const static int static_category = alert::tracker_notificati
on | alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual char const* what() const { return "tracker error"; } | | virtual char const* what() const { return "tracker error"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[400]; | |
| ret << tracker_alert::message() << " (" << status_co | | snprintf(ret, sizeof(ret), "%s (%d) %s (%d)" | |
| de << ") " | | , tracker_alert::message().c_str(), status_c | |
| << msg << " (" << times_in_row << ")"; | | ode | |
| return ret.str(); | | , msg.c_str(), times_in_row); | |
| | | return ret; | |
| } | | } | |
| | | | |
| int times_in_row; | | int times_in_row; | |
| int status_code; | | int status_code; | |
| std::string msg; | | std::string msg; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_warning_alert: tracker_alert | | struct TORRENT_EXPORT tracker_warning_alert: tracker_alert | |
| { | | { | |
| tracker_warning_alert(torrent_handle const& h | | tracker_warning_alert(torrent_handle const& h | |
| | | | |
| skipping to change at line 293 | | skipping to change at line 371 | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
| int incomplete; | | int incomplete; | |
| int complete; | | int complete; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new scrape_reply_alert(*this))
; } | | { return std::auto_ptr<alert>(new scrape_reply_alert(*this))
; } | |
| virtual char const* what() const { return "tracker scrape re
ply"; } | | virtual char const* what() const { return "tracker scrape re
ply"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[400]; | |
| ret << tracker_alert::message() << " scrape reply: " | | snprintf(ret, sizeof(ret), "%s scrape reply: %u %u" | |
| << incomplete | | , tracker_alert::message().c_str(), incomple | |
| << " " << complete; | | te, complete); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT scrape_failed_alert: tracker_alert | | struct TORRENT_EXPORT scrape_failed_alert: tracker_alert | |
| { | | { | |
| scrape_failed_alert(torrent_handle const& h | | scrape_failed_alert(torrent_handle const& h | |
| , std::string const& url_ | | , std::string const& url_ | |
|
| | | , error_code const& e) | |
| | | : tracker_alert(h, url_) | |
| | | , msg(e.message()) | |
| | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
| | | scrape_failed_alert(torrent_handle const& h | |
| | | , std::string const& url_ | |
| , std::string const& msg_) | | , std::string const& msg_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , msg(msg_) | | , msg(msg_) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
| std::string msg; | | std::string msg; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new scrape_failed_alert(*this)
); } | | { return std::auto_ptr<alert>(new scrape_failed_alert(*this)
); } | |
| const static int static_category = alert::tracker_notificati
on | alert::error_notification; | | const static int static_category = alert::tracker_notificati
on | alert::error_notification; | |
| | | | |
| skipping to change at line 338 | | skipping to change at line 423 | |
| , num_peers(np) | | , num_peers(np) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
| int num_peers; | | int num_peers; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new tracker_reply_alert(*this)
); } | | { return std::auto_ptr<alert>(new tracker_reply_alert(*this)
); } | |
| virtual char const* what() const { return "tracker reply"; } | | virtual char const* what() const { return "tracker reply"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[400]; | |
| ret << tracker_alert::message() << " received peers: | | snprintf(ret, sizeof(ret), "%s received peers: %u" | |
| " | | , tracker_alert::message().c_str(), num_peer | |
| << num_peers; | | s); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT dht_reply_alert: tracker_alert | | struct TORRENT_EXPORT dht_reply_alert: tracker_alert | |
| { | | { | |
| dht_reply_alert(torrent_handle const& h | | dht_reply_alert(torrent_handle const& h | |
| , int np) | | , int np) | |
| : tracker_alert(h, "") | | : tracker_alert(h, "") | |
| , num_peers(np) | | , num_peers(np) | |
| {} | | {} | |
| | | | |
| int num_peers; | | int num_peers; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new dht_reply_alert(*this)); } | | { return std::auto_ptr<alert>(new dht_reply_alert(*this)); } | |
| virtual char const* what() const { return "DHT reply"; } | | virtual char const* what() const { return "DHT reply"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[400]; | |
| ret << tracker_alert::message() << " received DHT pe | | snprintf(ret, sizeof(ret), "%s received DHT peers: % | |
| ers: " | | u" | |
| << num_peers; | | , tracker_alert::message().c_str(), num_peer | |
| return ret.str(); | | s); | |
| | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT tracker_announce_alert: tracker_alert | | struct TORRENT_EXPORT tracker_announce_alert: tracker_alert | |
| { | | { | |
| tracker_announce_alert(torrent_handle const& h | | tracker_announce_alert(torrent_handle const& h | |
| , std::string const& url_, int event_) | | , std::string const& url_, int event_) | |
| : tracker_alert(h, url_) | | : tracker_alert(h, url_) | |
| , event(event_) | | , event(event_) | |
| { TORRENT_ASSERT(!url.empty()); } | | { TORRENT_ASSERT(!url.empty()); } | |
| | | | |
| skipping to change at line 403 | | skipping to change at line 488 | |
| , piece_index(index) | | , piece_index(index) | |
| { TORRENT_ASSERT(index >= 0);} | | { TORRENT_ASSERT(index >= 0);} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new hash_failed_alert(*this));
} | | { return std::auto_ptr<alert>(new hash_failed_alert(*this));
} | |
| virtual char const* what() const { return "piece hash failed
"; } | | virtual char const* what() const { return "piece hash failed
"; } | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[400]; | |
| ret << torrent_alert::message() << " hash for piece | | snprintf(ret, sizeof(ret), "%s hash for piece %u fai | |
| " | | led" | |
| << piece_index << " failed"; | | , torrent_alert::message().c_str(), piece_in | |
| return ret.str(); | | dex); | |
| | | return ret; | |
| } | | } | |
| | | | |
| int piece_index; | | int piece_index; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_ban_alert: peer_alert | | struct TORRENT_EXPORT peer_ban_alert: peer_alert | |
| { | | { | |
|
| peer_ban_alert(torrent_handle h, tcp::endpoint const& ip | | peer_ban_alert(torrent_handle h, tcp::endpoint const& ep | |
| , peer_id const& pid) | | , peer_id const& peer_id) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new peer_ban_alert(*this)); } | | { return std::auto_ptr<alert>(new peer_ban_alert(*this)); } | |
| virtual char const* what() const { return "peer banned"; } | | virtual char const* what() const { return "peer banned"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| return peer_alert::message() + " banned peer"; | | return peer_alert::message() + " banned peer"; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert | | struct TORRENT_EXPORT peer_unsnubbed_alert: peer_alert | |
| { | | { | |
|
| peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const& | | peer_unsnubbed_alert(torrent_handle h, tcp::endpoint const& | |
| ip | | ep | |
| , peer_id const& pid) | | , peer_id const& peer_id) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new peer_unsnubbed_alert(*this
)); } | | { return std::auto_ptr<alert>(new peer_unsnubbed_alert(*this
)); } | |
| virtual char const* what() const { return "peer unsnubbed";
} | | virtual char const* what() const { return "peer unsnubbed";
} | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return peer_alert::message() + " peer unsnubbed"; | | return peer_alert::message() + " peer unsnubbed"; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_snubbed_alert: peer_alert | | struct TORRENT_EXPORT peer_snubbed_alert: peer_alert | |
| { | | { | |
|
| peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ip | | peer_snubbed_alert(torrent_handle h, tcp::endpoint const& ep | |
| , peer_id const& pid) | | , peer_id const& peer_id) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new peer_snubbed_alert(*this))
; } | | { return std::auto_ptr<alert>(new peer_snubbed_alert(*this))
; } | |
| virtual char const* what() const { return "peer snubbed"; } | | virtual char const* what() const { return "peer snubbed"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return peer_alert::message() + " peer snubbed"; | | return peer_alert::message() + " peer snubbed"; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_error_alert: peer_alert | | struct TORRENT_EXPORT peer_error_alert: peer_alert | |
| { | | { | |
|
| peer_error_alert(torrent_handle const& h, tcp::endpoint cons | | peer_error_alert(torrent_handle const& h, tcp::endpoint cons | |
| t& ip | | t& ep | |
| , peer_id const& pid, std::string const& msg_) | | , peer_id const& peer_id, error_code const& e) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| , msg(msg_) | | , error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new peer_error_alert(*this));
} | | { return std::auto_ptr<alert>(new peer_error_alert(*this));
} | |
| virtual char const* what() const { return "peer error"; } | | virtual char const* what() const { return "peer error"; } | |
| const static int static_category = alert::peer_notification; | | const static int static_category = alert::peer_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| error_code ec; | | error_code ec; | |
|
| return peer_alert::message() + " peer error: " + msg
; | | return peer_alert::message() + " peer error: " + err
or.message(); | |
| } | | } | |
| | | | |
|
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_connect_alert: peer_alert | | struct TORRENT_EXPORT peer_connect_alert: peer_alert | |
| { | | { | |
|
| peer_connect_alert(torrent_handle h, tcp::endpoint const& ip | | peer_connect_alert(torrent_handle h, tcp::endpoint const& ep | |
| , peer_id const& pid) | | , peer_id const& peer_id) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new peer_connect_alert(*this))
; } | | { return std::auto_ptr<alert>(new peer_connect_alert(*this))
; } | |
| virtual char const* what() const { return "connecting to pee
r"; } | | virtual char const* what() const { return "connecting to pee
r"; } | |
| const static int static_category = alert::debug_notification
; | | const static int static_category = alert::debug_notification
; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return peer_alert::message() + " connecting to peer"
; | | return peer_alert::message() + " connecting to peer"
; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_disconnected_alert: peer_alert | | struct TORRENT_EXPORT peer_disconnected_alert: peer_alert | |
| { | | { | |
|
| peer_disconnected_alert(torrent_handle const& h, tcp::endpoi | | peer_disconnected_alert(torrent_handle const& h, tcp::endpoi | |
| nt const& ip | | nt const& ep | |
| , peer_id const& pid, std::string const& msg_) | | , peer_id const& peer_id, error_code const& e) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| , msg(msg_) | | , error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new peer_disconnected_alert(*t
his)); } | | { return std::auto_ptr<alert>(new peer_disconnected_alert(*t
his)); } | |
| virtual char const* what() const { return "peer disconnected
"; } | | virtual char const* what() const { return "peer disconnected
"; } | |
| const static int static_category = alert::debug_notification
; | | const static int static_category = alert::debug_notification
; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| return peer_alert::message() + " disconnecting: " +
msg; | | return peer_alert::message() + " disconnecting: " +
error.message(); | |
| } | | } | |
| | | | |
|
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT invalid_request_alert: peer_alert | | struct TORRENT_EXPORT invalid_request_alert: peer_alert | |
| { | | { | |
|
| invalid_request_alert(torrent_handle const& h, tcp::endpoint | | invalid_request_alert(torrent_handle const& h, tcp::endpoint | |
| const& ip | | const& ep | |
| , peer_id const& pid, peer_request const& r) | | , peer_id const& peer_id, peer_request const& r) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| , request(r) | | , request(r) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new invalid_request_alert(*thi
s)); } | | { return std::auto_ptr<alert>(new invalid_request_alert(*thi
s)); } | |
| virtual char const* what() const { return "invalid piece req
uest"; } | | virtual char const* what() const { return "invalid piece req
uest"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << peer_alert::message() << " peer sent an inval | | snprintf(ret, sizeof(ret), "%s peer sent an invalid | |
| id piece request " | | piece request (piece: %u start: %u len: %u)" | |
| "( piece: " << request.piece << " start: " < | | , torrent_alert::message().c_str(), request. | |
| < request.start | | piece, request.start, request.length); | |
| << " len: " << request.length << ")"; | | return ret; | |
| return ret.str(); | | | |
| } | | } | |
| | | | |
| peer_request request; | | peer_request request; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_finished_alert: torrent_alert | | struct TORRENT_EXPORT torrent_finished_alert: torrent_alert | |
| { | | { | |
| torrent_finished_alert( | | torrent_finished_alert( | |
| const torrent_handle& h) | | const torrent_handle& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| | | | |
| skipping to change at line 581 | | skipping to change at line 681 | |
| | | | |
| int piece_index; | | int piece_index; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new piece_finished_alert(*this
)); } | | { return std::auto_ptr<alert>(new piece_finished_alert(*this
)); } | |
| virtual char const* what() const { return "piece finished do
wnloading"; } | | virtual char const* what() const { return "piece finished do
wnloading"; } | |
| const static int static_category = alert::progress_notificat
ion; | | const static int static_category = alert::progress_notificat
ion; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << torrent_alert::message() << " piece " << piec | | snprintf(ret, sizeof(ret), "%s piece: %u finished do | |
| e_index | | wnloading" | |
| << " finished downloading"; | | , torrent_alert::message().c_str(), piece_in | |
| return ret.str(); | | dex); | |
| | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT request_dropped_alert: peer_alert | | struct TORRENT_EXPORT request_dropped_alert: peer_alert | |
| { | | { | |
|
| request_dropped_alert(const torrent_handle& h, tcp::endpoint | | request_dropped_alert(const torrent_handle& h, tcp::endpoint | |
| const& ip | | const& ep | |
| , peer_id const& pid, int block_num, int piece_num) | | , peer_id const& peer_id, int block_num, int piece_n | |
| : peer_alert(h, ip, pid) | | um) | |
| | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new request_dropped_alert(*thi
s)); } | | { return std::auto_ptr<alert>(new request_dropped_alert(*thi
s)); } | |
| virtual char const* what() const { return "block request dro
pped"; } | | virtual char const* what() const { return "block request dro
pped"; } | |
| const static int static_category = alert::progress_notificat
ion | | const static int static_category = alert::progress_notificat
ion | |
| | alert::peer_notification; | | | alert::peer_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << peer_alert::message() << " peer dropped block | | snprintf(ret, sizeof(ret), "%s peer dropped block ( | |
| ( piece: " | | piece: %u block: %u)" | |
| << piece_index << " block: " << block_index | | , torrent_alert::message().c_str(), piece_in | |
| << ")"; | | dex, block_index); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_timeout_alert: peer_alert | | struct TORRENT_EXPORT block_timeout_alert: peer_alert | |
| { | | { | |
|
| block_timeout_alert(const torrent_handle& h, tcp::endpoint c | | block_timeout_alert(const torrent_handle& h, tcp::endpoint c | |
| onst& ip | | onst& ep | |
| , peer_id const& pid, int block_num, int piece_num) | | , peer_id const& peer_id, int block_num, int piece_n | |
| : peer_alert(h, ip, pid) | | um) | |
| | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new block_timeout_alert(*this)
); } | | { return std::auto_ptr<alert>(new block_timeout_alert(*this)
); } | |
| virtual char const* what() const { return "block timed out";
} | | virtual char const* what() const { return "block timed out";
} | |
| const static int static_category = alert::progress_notificat
ion | | const static int static_category = alert::progress_notificat
ion | |
| | alert::peer_notification; | | | alert::peer_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << peer_alert::message() << " peer timed out req | | snprintf(ret, sizeof(ret), "%s peer timed out reques | |
| uest ( piece: " | | t ( piece: %u block: %u)" | |
| << piece_index << " block: " << block_index | | , torrent_alert::message().c_str(), piece_in | |
| << ")"; | | dex, block_index); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_finished_alert: peer_alert | | struct TORRENT_EXPORT block_finished_alert: peer_alert | |
| { | | { | |
|
| block_finished_alert(const torrent_handle& h, tcp::endpoint | | block_finished_alert(const torrent_handle& h, tcp::endpoint | |
| const& ip | | const& ep | |
| , peer_id const& pid, int block_num, int piece_num) | | , peer_id const& peer_id, int block_num, int piece_n | |
| : peer_alert(h, ip, pid) | | um) | |
| | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new block_finished_alert(*this
)); } | | { return std::auto_ptr<alert>(new block_finished_alert(*this
)); } | |
| virtual char const* what() const { return "block finished do
wnloading"; } | | virtual char const* what() const { return "block finished do
wnloading"; } | |
| const static int static_category = alert::progress_notificat
ion; | | const static int static_category = alert::progress_notificat
ion; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << peer_alert::message() << " block finished dow | | snprintf(ret, sizeof(ret), "%s block finished downlo | |
| nloading ( piece: " | | ading (piece: %u block: %u)" | |
| << piece_index << " block: " << block_index | | , torrent_alert::message().c_str(), piece_in | |
| << ")"; | | dex, block_index); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_downloading_alert: peer_alert | | struct TORRENT_EXPORT block_downloading_alert: peer_alert | |
| { | | { | |
|
| block_downloading_alert(const torrent_handle& h, tcp::endpoi | | block_downloading_alert(const torrent_handle& h, tcp::endpoi | |
| nt const& ip | | nt const& ep | |
| , peer_id const& pid, char const* speedmsg, int bloc | | , peer_id const& peer_id, char const* speedmsg, int | |
| k_num, int piece_num) | | block_num, int piece_num) | |
| : peer_alert(h, ip, pid) | | : peer_alert(h, ep, peer_id) | |
| , peer_speedmsg(speedmsg) | | , peer_speedmsg(speedmsg) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
| char const* peer_speedmsg; | | char const* peer_speedmsg; | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new block_downloading_alert(*t
his)); } | | { return std::auto_ptr<alert>(new block_downloading_alert(*t
his)); } | |
| virtual char const* what() const { return "block requested";
} | | virtual char const* what() const { return "block requested";
} | |
| const static int static_category = alert::progress_notificat
ion; | | const static int static_category = alert::progress_notificat
ion; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << peer_alert::message() << " requested block ( | | snprintf(ret, sizeof(ret), "%s requested block (piec | |
| piece: " | | e: %u block: %u) %s" | |
| << piece_index << " block: " << block_index | | , torrent_alert::message().c_str(), piece_in | |
| << ") " << peer_speedmsg; | | dex, block_index, peer_speedmsg); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT unwanted_block_alert: peer_alert | | struct TORRENT_EXPORT unwanted_block_alert: peer_alert | |
| { | | { | |
|
| unwanted_block_alert(const torrent_handle& h, tcp::endpoint | | unwanted_block_alert(const torrent_handle& h, tcp::endpoint | |
| const& ip | | const& ep | |
| , peer_id const& pid, int block_num, int piece_num) | | , peer_id const& peer_id, int block_num, int piece_n | |
| : peer_alert(h, ip, pid) | | um) | |
| | | : peer_alert(h, ep, peer_id) | |
| , block_index(block_num) | | , block_index(block_num) | |
| , piece_index(piece_num) | | , piece_index(piece_num) | |
| { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | | { TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);} | |
| | | | |
| int block_index; | | int block_index; | |
| int piece_index; | | int piece_index; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new unwanted_block_alert(*this
)); } | | { return std::auto_ptr<alert>(new unwanted_block_alert(*this
)); } | |
| virtual char const* what() const { return "unwanted block re
ceived"; } | | virtual char const* what() const { return "unwanted block re
ceived"; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << peer_alert::message() << " received block not | | snprintf(ret, sizeof(ret), "%s received block not in | |
| in download queue ( piece: " | | download queue (piece: %u block: %u)" | |
| << piece_index << " block: " << block_index | | , torrent_alert::message().c_str(), piece_in | |
| << ")"; | | dex, block_index); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT storage_moved_alert: torrent_alert | | struct TORRENT_EXPORT storage_moved_alert: torrent_alert | |
| { | | { | |
| storage_moved_alert(torrent_handle const& h, std::string con
st& path_) | | storage_moved_alert(torrent_handle const& h, std::string con
st& path_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , path(path_) | | , path(path_) | |
| {} | | {} | |
| | | | |
| | | | |
| skipping to change at line 764 | | skipping to change at line 864 | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " storage move fai
led: " | | return torrent_alert::message() + " storage move fai
led: " | |
| + error.message(); | | + error.message(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert | | struct TORRENT_EXPORT torrent_deleted_alert: torrent_alert | |
| { | | { | |
|
| torrent_deleted_alert(torrent_handle const& h) | | torrent_deleted_alert(torrent_handle const& h, sha1_hash con
st& ih) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
|
| {} | | { info_hash = ih; } | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new torrent_deleted_alert(*thi
s)); } | | { return std::auto_ptr<alert>(new torrent_deleted_alert(*thi
s)); } | |
| virtual char const* what() const { return "torrent deleted";
} | | virtual char const* what() const { return "torrent deleted";
} | |
| const static int static_category = alert::storage_notificati
on; | | const static int static_category = alert::storage_notificati
on; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " deleted"; | | return torrent_alert::message() + " deleted"; | |
| } | | } | |
|
| | | | |
| | | sha1_hash info_hash; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert | | struct TORRENT_EXPORT torrent_delete_failed_alert: torrent_alert | |
| { | | { | |
|
| torrent_delete_failed_alert(torrent_handle const& h, std::st
ring msg_) | | torrent_delete_failed_alert(torrent_handle const& h, error_c
ode const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
|
| , msg(msg_) | | , error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
|
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new torrent_delete_failed_aler
t(*this)); } | | { return std::auto_ptr<alert>(new torrent_delete_failed_aler
t(*this)); } | |
| virtual char const* what() const { return "torrent delete fa
iled"; } | | virtual char const* what() const { return "torrent delete fa
iled"; } | |
| const static int static_category = alert::storage_notificati
on | | const static int static_category = alert::storage_notificati
on | |
| | alert::error_notification; | | | alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " torrent deletion
failed: " | | return torrent_alert::message() + " torrent deletion
failed: " | |
|
| + msg; | | + error.message(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT save_resume_data_alert: torrent_alert | | struct TORRENT_EXPORT save_resume_data_alert: torrent_alert | |
| { | | { | |
| save_resume_data_alert(boost::shared_ptr<entry> const& rd | | save_resume_data_alert(boost::shared_ptr<entry> const& rd | |
| , torrent_handle const& h) | | , torrent_handle const& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , resume_data(rd) | | , resume_data(rd) | |
| {} | | {} | |
| | | | |
| skipping to change at line 825 | | skipping to change at line 935 | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " resume data gene
rated"; | | return torrent_alert::message() + " resume data gene
rated"; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert | | struct TORRENT_EXPORT save_resume_data_failed_alert: torrent_alert | |
| { | | { | |
| save_resume_data_failed_alert(torrent_handle const& h | | save_resume_data_failed_alert(torrent_handle const& h | |
|
| , std::string const& msg_) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
|
| , msg(msg_) | | , error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
| | | error_code error; | |
| | | | |
|
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new save_resume_data_failed_al
ert(*this)); } | | { return std::auto_ptr<alert>(new save_resume_data_failed_al
ert(*this)); } | |
| virtual char const* what() const { return "save resume data
failed"; } | | virtual char const* what() const { return "save resume data
failed"; } | |
| const static int static_category = alert::storage_notificati
on | | const static int static_category = alert::storage_notificati
on | |
| | alert::error_notification; | | | alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " resume data was
not generated: " | | return torrent_alert::message() + " resume data was
not generated: " | |
|
| + msg; | | + error.message(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_paused_alert: torrent_alert | | struct TORRENT_EXPORT torrent_paused_alert: torrent_alert | |
| { | | { | |
| torrent_paused_alert(torrent_handle const& h) | | torrent_paused_alert(torrent_handle const& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| | | | |
| skipping to change at line 899 | | skipping to change at line 1017 | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " checked"; | | return torrent_alert::message() + " checked"; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT url_seed_alert: torrent_alert | | struct TORRENT_EXPORT url_seed_alert: torrent_alert | |
| { | | { | |
| url_seed_alert( | | url_seed_alert( | |
| torrent_handle const& h | | torrent_handle const& h | |
|
| , const std::string& url_ | | , std::string const& url_ | |
| , const std::string& msg_) | | , error_code const& e) | |
| | | : torrent_alert(h) | |
| | | , url(url_) | |
| | | , msg(e.message()) | |
| | | {} | |
| | | | |
| | | url_seed_alert( | |
| | | torrent_handle const& h | |
| | | , std::string const& url_ | |
| | | , std::string const& msg_) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , url(url_) | | , url(url_) | |
| , msg(msg_) | | , msg(msg_) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new url_seed_alert(*this)); } | | { return std::auto_ptr<alert>(new url_seed_alert(*this)); } | |
| virtual char const* what() const { return "web seed error";
} | | virtual char const* what() const { return "web seed error";
} | |
| const static int static_category = alert::peer_notification
| alert::error_notification; | | const static int static_category = alert::peer_notification
| alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| | | | |
| skipping to change at line 925 | | skipping to change at line 1052 | |
| } | | } | |
| | | | |
| std::string url; | | std::string url; | |
| std::string msg; | | std::string msg; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT file_error_alert: torrent_alert | | struct TORRENT_EXPORT file_error_alert: torrent_alert | |
| { | | { | |
| file_error_alert( | | file_error_alert( | |
| std::string const& f | | std::string const& f | |
|
| , const torrent_handle& h | | , torrent_handle const& h | |
| , const std::string& msg_) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| , file(f) | | , file(f) | |
|
| , msg(msg_) | | , error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
| std::string file; | | std::string file; | |
|
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new file_error_alert(*this));
} | | { return std::auto_ptr<alert>(new file_error_alert(*this));
} | |
| virtual char const* what() const { return "file error"; } | | virtual char const* what() const { return "file error"; } | |
| const static int static_category = alert::status_notificatio
n | | const static int static_category = alert::status_notificatio
n | |
| | alert::error_notification | | | alert::error_notification | |
| | alert::storage_notification; | | | alert::storage_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| return torrent_alert::message() + " file (" + file +
") error: " | | return torrent_alert::message() + " file (" + file +
") error: " | |
|
| + msg; | | + error.message(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT metadata_failed_alert: torrent_alert | | struct TORRENT_EXPORT metadata_failed_alert: torrent_alert | |
| { | | { | |
| metadata_failed_alert(const torrent_handle& h) | | metadata_failed_alert(const torrent_handle& h) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
| {} | | {} | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| | | | |
| skipping to change at line 1047 | | skipping to change at line 1182 | |
| tcp::endpoint endpoint; | | tcp::endpoint endpoint; | |
| error_code error; | | error_code error; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new listen_failed_alert(*this)
); } | | { return std::auto_ptr<alert>(new listen_failed_alert(*this)
); } | |
| virtual char const* what() const { return "listen failed"; } | | virtual char const* what() const { return "listen failed"; } | |
| const static int static_category = alert::status_notificatio
n | alert::error_notification; | | const static int static_category = alert::status_notificatio
n | alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| error_code ec; | | char ret[200]; | |
| std::stringstream ret; | | snprintf(ret, sizeof(ret), "listening on %s failed: | |
| ret << "listening on " << endpoint | | %s" | |
| << " failed: " << error.message(); | | , print_endpoint(endpoint).c_str(), error.me | |
| return ret.str(); | | ssage().c_str()); | |
| | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT listen_succeeded_alert: alert | | struct TORRENT_EXPORT listen_succeeded_alert: alert | |
| { | | { | |
| listen_succeeded_alert(tcp::endpoint const& ep) | | listen_succeeded_alert(tcp::endpoint const& ep) | |
| : endpoint(ep) | | : endpoint(ep) | |
| {} | | {} | |
| | | | |
| tcp::endpoint endpoint; | | tcp::endpoint endpoint; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new listen_succeeded_alert(*th
is)); } | | { return std::auto_ptr<alert>(new listen_succeeded_alert(*th
is)); } | |
| virtual char const* what() const { return "listen succeeded"
; } | | virtual char const* what() const { return "listen succeeded"
; } | |
| const static int static_category = alert::status_notificatio
n; | | const static int static_category = alert::status_notificatio
n; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| error_code ec; | | char ret[200]; | |
| std::stringstream ret; | | snprintf(ret, sizeof(ret), "successfully listening o | |
| ret << "successfully listening on " << endpoint; | | n %s", print_endpoint(endpoint).c_str()); | |
| return ret.str(); | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT portmap_error_alert: alert | | struct TORRENT_EXPORT portmap_error_alert: alert | |
| { | | { | |
|
| portmap_error_alert(int i, int t, const std::string& msg_) | | portmap_error_alert(int i, int t, error_code const& e) | |
| : mapping(i), type(t), msg(msg_) | | : mapping(i), type(t), error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
| int mapping; | | int mapping; | |
| int type; | | int type; | |
|
| | | error_code error; | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new portmap_error_alert(*this)
); } | | { return std::auto_ptr<alert>(new portmap_error_alert(*this)
); } | |
| virtual char const* what() const { return "port map error";
} | | virtual char const* what() const { return "port map error";
} | |
| const static int static_category = alert::port_mapping_notif
ication | | const static int static_category = alert::port_mapping_notif
ication | |
| | alert::error_notification; | | | alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| static char const* type_str[] = {"NAT-PMP", "UPnP"}; | | static char const* type_str[] = {"NAT-PMP", "UPnP"}; | |
| return std::string("could not map port using ") + ty
pe_str[type] | | return std::string("could not map port using ") + ty
pe_str[type] | |
|
| + ": " + msg; | | + ": " + error.message(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT portmap_alert: alert | | struct TORRENT_EXPORT portmap_alert: alert | |
| { | | { | |
| portmap_alert(int i, int port, int t) | | portmap_alert(int i, int port, int t) | |
| : mapping(i), external_port(port), type(t) | | : mapping(i), external_port(port), type(t) | |
| {} | | {} | |
| | | | |
| int mapping; | | int mapping; | |
| | | | |
| skipping to change at line 1119 | | skipping to change at line 1259 | |
| int type; | | int type; | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new portmap_alert(*this)); } | | { return std::auto_ptr<alert>(new portmap_alert(*this)); } | |
| virtual char const* what() const { return "port map succeede
d"; } | | virtual char const* what() const { return "port map succeede
d"; } | |
| const static int static_category = alert::port_mapping_notif
ication; | | const static int static_category = alert::port_mapping_notif
ication; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| static char const* type_str[] = {"NAT-PMP", "UPnP"}; | | static char const* type_str[] = {"NAT-PMP", "UPnP"}; | |
|
| std::stringstream ret; | | char ret[200]; | |
| ret << "successfully mapped port using " << type_str | | snprintf(ret, sizeof(ret), "successfully mapped port | |
| [type] | | using %s. external port: %u" | |
| << ". external port: " << external_port; | | , type_str[type], external_port); | |
| return ret.str(); | | return ret; | |
| | | } | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT portmap_log_alert: alert | |
| | | { | |
| | | portmap_log_alert(int t, std::string const& m) | |
| | | : type(t), msg(m) | |
| | | {} | |
| | | | |
| | | int type; | |
| | | std::string msg; | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new portmap_log_alert(*this)); | |
| | | } | |
| | | virtual char const* what() const { return "port map log"; } | |
| | | const static int static_category = alert::port_mapping_notif | |
| | | ication; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual std::string message() const | |
| | | { | |
| | | static char const* type_str[] = {"NAT-PMP", "UPnP"}; | |
| | | char ret[600]; | |
| | | snprintf(ret, sizeof(ret), "%s: %s", type_str[type], | |
| | | msg.c_str()); | |
| | | return ret; | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert | | struct TORRENT_EXPORT fastresume_rejected_alert: torrent_alert | |
| { | | { | |
| fastresume_rejected_alert(torrent_handle const& h | | fastresume_rejected_alert(torrent_handle const& h | |
|
| , std::string const& msg_) | | , error_code const& e) | |
| : torrent_alert(h) | | : torrent_alert(h) | |
|
| , msg(msg_) | | , error(e) | |
| {} | | { | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| | | msg = error.message(); | |
| | | #endif | |
| | | } | |
| | | | |
|
| | | error_code error; | |
| | | | |
| | | #ifndef TORRENT_NO_DEPRECATE | |
| std::string msg; | | std::string msg; | |
|
| | | #endif | |
| | | | |
| virtual std::auto_ptr<alert> clone() const | | virtual std::auto_ptr<alert> clone() const | |
| { return std::auto_ptr<alert>(new fastresume_rejected_alert(
*this)); } | | { return std::auto_ptr<alert>(new fastresume_rejected_alert(
*this)); } | |
| virtual char const* what() const { return "resume data rejec
ted"; } | | virtual char const* what() const { return "resume data rejec
ted"; } | |
| const static int static_category = alert::status_notificatio
n | | const static int static_category = alert::status_notificatio
n | |
| | alert::error_notification; | | | alert::error_notification; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
|
| return torrent_alert::message() + " fast resume reje
cted: " + msg; | | return torrent_alert::message() + " fast resume reje
cted: " + error.message(); | |
| } | | } | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT peer_blocked_alert: alert | | struct TORRENT_EXPORT peer_blocked_alert: alert | |
| { | | { | |
| peer_blocked_alert(address const& ip_) | | peer_blocked_alert(address const& ip_) | |
| : ip(ip_) | | : ip(ip_) | |
| {} | | {} | |
| | | | |
| address ip; | | address ip; | |
| | | | |
| skipping to change at line 1167 | | skipping to change at line 1338 | |
| { return std::auto_ptr<alert>(new peer_blocked_alert(*this))
; } | | { return std::auto_ptr<alert>(new peer_blocked_alert(*this))
; } | |
| virtual char const* what() const { return "peer blocked"; } | | virtual char const* what() const { return "peer blocked"; } | |
| const static int static_category = alert::ip_block_notificat
ion; | | const static int static_category = alert::ip_block_notificat
ion; | |
| virtual int category() const { return static_category; } | | virtual int category() const { return static_category; } | |
| virtual std::string message() const | | virtual std::string message() const | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| return "blocked peer: " + ip.to_string(ec); | | return "blocked peer: " + ip.to_string(ec); | |
| } | | } | |
| }; | | }; | |
|
| | | | |
| | | struct TORRENT_EXPORT dht_announce_alert: alert | |
| | | { | |
| | | dht_announce_alert(address const& ip_, int port_ | |
| | | , sha1_hash const& info_hash_) | |
| | | : ip(ip_) | |
| | | , port(port_) | |
| | | , info_hash(info_hash_) | |
| | | {} | |
| | | | |
| | | address ip; | |
| | | int port; | |
| | | sha1_hash info_hash; | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new dht_announce_alert(*this)) | |
| | | ; } | |
| | | virtual char const* what() const { return "incoming dht anno | |
| | | unce"; } | |
| | | const static int static_category = alert::dht_notification; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual std::string message() const | |
| | | { | |
| | | error_code ec; | |
| | | char ih_hex[41]; | |
| | | to_hex((const char*)&info_hash[0], 20, ih_hex); | |
| | | char msg[200]; | |
| | | snprintf(msg, sizeof(msg), "incoming dht announce: % | |
| | | s:%u (%s)" | |
| | | , ip.to_string(ec).c_str(), port, ih_hex); | |
| | | return msg; | |
| | | } | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT dht_get_peers_alert: alert | |
| | | { | |
| | | dht_get_peers_alert(sha1_hash const& info_hash_) | |
| | | : info_hash(info_hash_) | |
| | | {} | |
| | | | |
| | | sha1_hash info_hash; | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new dht_get_peers_alert(*this) | |
| | | ); } | |
| | | virtual char const* what() const { return "incoming dht get_ | |
| | | peers request"; } | |
| | | const static int static_category = alert::dht_notification; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual std::string message() const | |
| | | { | |
| | | char ih_hex[41]; | |
| | | to_hex((const char*)&info_hash[0], 20, ih_hex); | |
| | | char msg[200]; | |
| | | snprintf(msg, sizeof(msg), "incoming dht get_peers: | |
| | | %s", ih_hex); | |
| | | return msg; | |
| | | } | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT stats_alert: torrent_alert | |
| | | { | |
| | | stats_alert(torrent_handle const& h, int interval | |
| | | , stat const& s); | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new stats_alert(*this)); } | |
| | | const static int static_category = alert::stats_notification | |
| | | ; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual char const* what() const { return "stats_alert"; } | |
| | | | |
| | | virtual std::string message() const; | |
| | | | |
| | | enum stats_channel | |
| | | { | |
| | | upload_payload, | |
| | | upload_protocol, | |
| | | upload_ip_protocol, | |
| | | upload_dht_protocol, | |
| | | upload_tracker_protocol, | |
| | | download_payload, | |
| | | download_protocol, | |
| | | download_ip_protocol, | |
| | | download_dht_protocol, | |
| | | download_tracker_protocol, | |
| | | num_channels | |
| | | }; | |
| | | | |
| | | int transferred[num_channels]; | |
| | | int interval; | |
| | | }; | |
| | | | |
| | | struct TORRENT_EXPORT cache_flushed_alert: torrent_alert | |
| | | { | |
| | | cache_flushed_alert(torrent_handle const& h); | |
| | | | |
| | | virtual std::auto_ptr<alert> clone() const | |
| | | { return std::auto_ptr<alert>(new cache_flushed_alert(*this) | |
| | | ); } | |
| | | const static int static_category = alert::storage_notificati | |
| | | on; | |
| | | virtual int category() const { return static_category; } | |
| | | virtual char const* what() const { return "cache_flushed_ale | |
| | | rt"; } | |
| | | }; | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 79 change blocks. |
| 176 lines changed or deleted | | 478 lines changed or added | |
|
| bandwidth_manager.hpp | | bandwidth_manager.hpp | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED | | #ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED | |
| #define TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED | | #define TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED | |
| | | | |
|
| #include <boost/shared_ptr.hpp> | | | |
| #include <boost/intrusive_ptr.hpp> | | #include <boost/intrusive_ptr.hpp> | |
|
| #include <boost/function.hpp> | | | |
| #include <boost/bind.hpp> | | | |
| #include <boost/integer_traits.hpp> | | | |
| #include <boost/thread/mutex.hpp> | | | |
| #include <deque> | | | |
| | | | |
| #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | | #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | |
| #include <fstream> | | #include <fstream> | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/invariant_check.hpp" | | #include "libtorrent/invariant_check.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/bandwidth_limit.hpp" | | #include "libtorrent/bandwidth_limit.hpp" | |
| #include "libtorrent/bandwidth_queue_entry.hpp" | | #include "libtorrent/bandwidth_queue_entry.hpp" | |
| | | | |
|
| using boost::weak_ptr; | | | |
| using boost::shared_ptr; | | | |
| using boost::intrusive_ptr; | | using boost::intrusive_ptr; | |
|
| using boost::bind; | | | |
| | | | |
| namespace libtorrent { | | namespace libtorrent { | |
| | | | |
|
| // the maximum block of bandwidth quota to | | template<class PeerConnection> | |
| // hand out is 33kB. The block size may | | | |
| // be smaller on lower limits | | | |
| enum | | | |
| { | | | |
| max_bandwidth_block_size = 33000, | | | |
| min_bandwidth_block_size = 400 | | | |
| }; | | | |
| | | | |
| const time_duration bw_window_size = seconds(1); | | | |
| | | | |
| template<class PeerConnection, class Torrent> | | | |
| struct history_entry | | | |
| { | | | |
| history_entry(intrusive_ptr<PeerConnection> p, weak_ptr<Torrent> t | | | |
| , int a, ptime exp) | | | |
| : expires_at(exp), amount(a), peer(p), tor(t) {} | | | |
| history_entry(int a, ptime exp) | | | |
| : expires_at(exp), amount(a), peer(), tor() {} | | | |
| ptime expires_at; | | | |
| int amount; | | | |
| intrusive_ptr<PeerConnection> peer; | | | |
| weak_ptr<Torrent> tor; | | | |
| }; | | | |
| | | | |
| template<class T> | | | |
| T clamp(T val, T ceiling, T floor) | | | |
| { | | | |
| TORRENT_ASSERT(ceiling >= floor); | | | |
| if (val >= ceiling) return ceiling; | | | |
| else if (val <= floor) return floor; | | | |
| return val; | | | |
| } | | | |
| | | | |
| template<class T> | | | |
| struct assign_at_exit | | | |
| { | | | |
| assign_at_exit(T& var, T val): var_(var), val_(val) {} | | | |
| ~assign_at_exit() { var_ = val_; } | | | |
| T& var_; | | | |
| T val_; | | | |
| }; | | | |
| | | | |
| template<class PeerConnection, class Torrent> | | | |
| struct bandwidth_manager | | struct bandwidth_manager | |
| { | | { | |
|
| bandwidth_manager(io_service& ios, int channel | | bandwidth_manager(int channel | |
| #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | | #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | |
| , bool log = false | | , bool log = false | |
| #endif | | #endif | |
| ) | | ) | |
|
| : m_ios(ios) | | : m_queued_bytes(0) | |
| , m_history_timer(m_ios) | | | |
| , m_limit(bandwidth_limit::inf) | | | |
| , m_drain_quota(0) | | | |
| , m_current_quota(0) | | | |
| , m_channel(channel) | | , m_channel(channel) | |
|
| , m_in_hand_out_bandwidth(false) | | | |
| , m_abort(false) | | , m_abort(false) | |
| { | | { | |
| #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | | #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | |
| if (log) | | if (log) | |
| m_log.open("bandwidth_limiter.log", std::ios::trunc)
; | | m_log.open("bandwidth_limiter.log", std::ios::trunc)
; | |
| m_start = time_now(); | | m_start = time_now(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| void drain(int bytes) | | | |
| { | | | |
| mutex_t::scoped_lock l(m_mutex); | | | |
| TORRENT_ASSERT(bytes >= 0); | | | |
| m_drain_quota += bytes; | | | |
| if (m_drain_quota > m_limit * 5) m_drain_quota = m_limit * 5 | | | |
| ; | | | |
| } | | | |
| | | | |
| void throttle(int limit) | | | |
| { | | | |
| mutex_t::scoped_lock l(m_mutex); | | | |
| TORRENT_ASSERT(limit >= 0); | | | |
| m_limit = limit; | | | |
| } | | | |
| | | | |
| int throttle() const | | | |
| { | | | |
| mutex_t::scoped_lock l(m_mutex); | | | |
| return m_limit; | | | |
| } | | | |
| | | | |
| void close() | | void close() | |
| { | | { | |
|
| mutex_t::scoped_lock l(m_mutex); | | | |
| m_abort = true; | | m_abort = true; | |
| m_queue.clear(); | | m_queue.clear(); | |
|
| m_history.clear(); | | m_queued_bytes = 0; | |
| m_current_quota = 0; | | | |
| error_code ec; | | error_code ec; | |
|
| m_history_timer.cancel(ec); | | | |
| } | | } | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| bool is_queued(PeerConnection const* peer) const | | bool is_queued(PeerConnection const* peer) const | |
| { | | { | |
|
| mutex_t::scoped_lock l(m_mutex); | | | |
| return is_queued(peer); | | | |
| } | | | |
| | | | |
| bool is_queued(PeerConnection const* peer, boost::mutex::scoped_lock | | | |
| & l) const | | | |
| { | | | |
| for (typename queue_t::const_iterator i = m_queue.begin() | | for (typename queue_t::const_iterator i = m_queue.begin() | |
| , end(m_queue.end()); i != end; ++i) | | , end(m_queue.end()); i != end; ++i) | |
| { | | { | |
| if (i->peer.get() == peer) return true; | | if (i->peer.get() == peer) return true; | |
| } | | } | |
| return false; | | return false; | |
| } | | } | |
|
| | | | |
| bool is_in_history(PeerConnection const* peer) const | | | |
| { | | | |
| mutex_t::scoped_lock l(m_mutex); | | | |
| return is_in_history(peer, l); | | | |
| } | | | |
| | | | |
| bool is_in_history(PeerConnection const* peer, boost::mutex::scoped_ | | | |
| lock& l) const | | | |
| { | | | |
| for (typename history_t::const_iterator i | | | |
| = m_history.begin(), end(m_history.end()); i != end; | | | |
| ++i) | | | |
| { | | | |
| if (i->peer.get() == peer) return true; | | | |
| } | | | |
| return false; | | | |
| } | | | |
| #endif | | #endif | |
| | | | |
| int queue_size() const | | int queue_size() const | |
| { | | { | |
|
| mutex_t::scoped_lock l(m_mutex); | | | |
| return m_queue.size(); | | return m_queue.size(); | |
| } | | } | |
| | | | |
|
| | | int queued_bytes() const | |
| | | { | |
| | | return m_queued_bytes; | |
| | | } | |
| | | | |
| // non prioritized means that, if there's a line for bandwidth, | | // non prioritized means that, if there's a line for bandwidth, | |
| // others will cut in front of the non-prioritized peers. | | // others will cut in front of the non-prioritized peers. | |
| // this is used by web seeds | | // this is used by web seeds | |
| void request_bandwidth(intrusive_ptr<PeerConnection> const& peer | | void request_bandwidth(intrusive_ptr<PeerConnection> const& peer | |
|
| , int blk, int priority) | | , int blk, int priority | |
| | | , bandwidth_channel* chan1 = 0 | |
| | | , bandwidth_channel* chan2 = 0 | |
| | | , bandwidth_channel* chan3 = 0 | |
| | | , bandwidth_channel* chan4 = 0 | |
| | | , bandwidth_channel* chan5 = 0 | |
| | | ) | |
| { | | { | |
|
| mutex_t::scoped_lock l(m_mutex); | | | |
| INVARIANT_CHECK; | | INVARIANT_CHECK; | |
| if (m_abort) return; | | if (m_abort) return; | |
|
| TORRENT_ASSERT(blk > 0); | | | |
| TORRENT_ASSERT(!is_queued(peer.get(), l)); | | | |
| | | | |
|
| // make sure this peer isn't already in line | | TORRENT_ASSERT(blk > 0); | |
| // waiting for bandwidth | | TORRENT_ASSERT(priority > 0); | |
| TORRENT_ASSERT(peer->max_assignable_bandwidth(m_channel) > 0 | | TORRENT_ASSERT(!is_queued(peer.get())); | |
| ); | | | |
| | | | |
|
| typename queue_t::reverse_iterator i(m_queue.rbegin()); | | bw_request<PeerConnection> bwr(peer, blk, priority); | |
| while (i != m_queue.rend() && priority > i->priority) | | int i = 0; | |
| | | if (chan1 && chan1->throttle() > 0) bwr.channel[i++] = chan1 | |
| | | ; | |
| | | if (chan2 && chan2->throttle() > 0) bwr.channel[i++] = chan2 | |
| | | ; | |
| | | if (chan3 && chan3->throttle() > 0) bwr.channel[i++] = chan3 | |
| | | ; | |
| | | if (chan4 && chan4->throttle() > 0) bwr.channel[i++] = chan4 | |
| | | ; | |
| | | if (chan5 && chan5->throttle() > 0) bwr.channel[i++] = chan5 | |
| | | ; | |
| | | if (i == 0) | |
| { | | { | |
|
| ++i->priority; | | // the connection is not rate limited by any of its | |
| ++i; | | // bandwidth channels, or it doesn't belong to any | |
| | | // channels. There's no point in adding it to | |
| | | // the queue, just satisfy the request immediately | |
| | | bwr.peer->assign_bandwidth(m_channel, blk); | |
| | | return; | |
| } | | } | |
|
| m_queue.insert(i.base(), bw_queue_entry<PeerConnection, Torr | | m_queued_bytes += blk; | |
| ent>(peer, blk, priority)); | | m_queue.push_back(bwr); | |
| if (!m_queue.empty()) hand_out_bandwidth(l); | | | |
| } | | } | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const | | void check_invariant() const | |
| { | | { | |
|
| int current_quota = 0; | | int queued = 0; | |
| for (typename history_t::const_iterator i | | for (typename queue_t::const_iterator i = m_queue.begin() | |
| = m_history.begin(), end(m_history.end()); i != end; | | , end(m_queue.end()); i != end; ++i) | |
| ++i) | | | |
| { | | | |
| current_quota += i->amount; | | | |
| } | | | |
| TORRENT_ASSERT(current_quota == m_current_quota); | | | |
| | | | |
| typename queue_t::const_iterator j = m_queue.begin(); | | | |
| if (j != m_queue.end()) | | | |
| { | | { | |
|
| ++j; | | queued += i->request_size - i->assigned; | |
| for (typename queue_t::const_iterator i = m_queue.be | | | |
| gin() | | | |
| , end(m_queue.end()); i != end && j != end; | | | |
| ++i, ++j) | | | |
| TORRENT_ASSERT(i->priority >= j->priority); | | | |
| } | | } | |
|
| | | TORRENT_ASSERT(queued == m_queued_bytes); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| private: | | void update_quotas(time_duration const& dt) | |
| | | | |
| void add_history_entry(history_entry<PeerConnection, Torrent> const& | | | |
| e) | | | |
| { | | | |
| INVARIANT_CHECK; | | | |
| | | | |
| m_history.push_front(e); | | | |
| m_current_quota += e.amount; | | | |
| // in case the size > 1 there is already a timer | | | |
| // active that will be invoked, no need to set one up | | | |
| | | | |
| #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | | | |
| m_log << std::setw(7) << total_milliseconds(time_now() - m_s | | | |
| tart) << " + " | | | |
| " queue: " << std::setw(3) << m_queue.size() | | | |
| << " used: " << std::setw(7) << m_current_quota | | | |
| << " limit: " << std::setw(7) << m_limit | | | |
| << " history: " << std::setw(3) << m_history.size() | | | |
| << std::endl; | | | |
| #endif | | | |
| if (m_history.size() > 1) return; | | | |
| | | | |
| if (m_abort) return; | | | |
| | | | |
| error_code ec; | | | |
| // TORRENT_ASSERT(e.expires_at > time_now()); | | | |
| m_history_timer.expires_at(e.expires_at, ec); | | | |
| m_history_timer.async_wait(bind(&bandwidth_manager::on_histo | | | |
| ry_expire, this, _1)); | | | |
| } | | | |
| | | | |
| void on_history_expire(error_code const& e) | | | |
| { | | { | |
|
| if (e) return; | | | |
| | | | |
| mutex_t::scoped_lock l(m_mutex); | | | |
| if (m_abort) return; | | if (m_abort) return; | |
|
| INVARIANT_CHECK; | | if (m_queue.empty()) return; | |
| | | | |
| TORRENT_ASSERT(!m_history.empty()); | | | |
| | | | |
| ptime now(time_now()); | | | |
| while (!m_history.empty() && m_history.back().expires_at <= | | | |
| now) | | | |
| { | | | |
| history_entry<PeerConnection, Torrent> e = m_history | | | |
| .back(); | | | |
| m_history.pop_back(); | | | |
| m_current_quota -= e.amount; | | | |
| TORRENT_ASSERT(m_current_quota >= 0); | | | |
| | | | |
| #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | | | |
| m_log << std::setw(7) << total_milliseconds(time_now | | | |
| () - m_start) << " - " | | | |
| " queue: " << std::setw(3) << m_queue.size() | | | |
| << " used: " << std::setw(7) << m_current_qu | | | |
| ota | | | |
| << " limit: " << std::setw(7) << m_limit | | | |
| << " history: " << std::setw(3) << m_history | | | |
| .size() | | | |
| << std::endl; | | | |
| #endif | | | |
| intrusive_ptr<PeerConnection> c = e.peer; | | | |
| if (!c) continue; | | | |
| shared_ptr<Torrent> t = e.tor.lock(); | | | |
| l.unlock(); | | | |
| if (!c->is_disconnecting()) c->expire_bandwidth(m_ch | | | |
| annel, e.amount); | | | |
| if (t) t->expire_bandwidth(m_channel, e.amount); | | | |
| l.lock(); | | | |
| } | | | |
| | | | |
| // now, wait for the next chunk to expire | | | |
| if (!m_history.empty() && !m_abort) | | | |
| { | | | |
| error_code ec; | | | |
| TORRENT_ASSERT(m_history.back().expires_at > now); | | | |
| m_history_timer.expires_at(m_history.back().expires_ | | | |
| at, ec); | | | |
| m_history_timer.async_wait(bind(&bandwidth_manager:: | | | |
| on_history_expire, this, _1)); | | | |
| } | | | |
| | | | |
| // since some bandwidth just expired, it | | | |
| // means we can hand out more (in case there | | | |
| // are still consumers in line) | | | |
| if (!m_queue.empty()) hand_out_bandwidth(l); | | | |
| } | | | |
| | | | |
| void hand_out_bandwidth(boost::mutex::scoped_lock& l) | | | |
| { | | | |
| // if we're already handing out bandwidth, just return back | | | |
| // to the loop further down on the callstack | | | |
| if (m_in_hand_out_bandwidth) return; | | | |
| m_in_hand_out_bandwidth = true; | | | |
| // set it to false when exiting function | | | |
| assign_at_exit<bool> sg(m_in_hand_out_bandwidth, false); | | | |
| | | | |
| INVARIANT_CHECK; | | INVARIANT_CHECK; | |
| | | | |
|
| ptime now(time_now()); | | int dt_milliseconds = total_milliseconds(dt); | |
| | | if (dt_milliseconds > 3000) dt_milliseconds = 3000; | |
| int limit = m_limit; | | | |
| | | | |
|
| // available bandwidth to hand out | | // for each bandwidth channel, call update_quota(dt) | |
| int amount = limit - m_current_quota; | | | |
| | | | |
|
| if (amount <= 0) return; | | std::vector<bandwidth_channel*> channels; | |
| | | | |
|
| if (m_drain_quota > 0) | | for (typename queue_t::iterator i = m_queue.begin(); | |
| | | i != m_queue.end();) | |
| { | | { | |
|
| int drain_amount = (std::min)(m_drain_quota, amount) | | if (i->peer->is_disconnecting()) | |
| ; | | { | |
| m_drain_quota -= drain_amount; | | m_queued_bytes -= i->request_size - i->assig | |
| amount -= drain_amount; | | ned; | |
| add_history_entry(history_entry<PeerConnection, Torr | | | |
| ent>( | | | |
| drain_amount, now + bw_window_size)); | | | |
| } | | | |
| | | | |
|
| queue_t tmp; | | // return all assigned quota to all the | |
| while (!m_queue.empty() && amount > 0) | | // bandwidth channels this peer belongs to | |
| { | | for (int j = 0; j < 5 && i->channel[j]; ++j) | |
| bw_queue_entry<PeerConnection, Torrent> qe = m_queue | | { | |
| .front(); | | bandwidth_channel* bwc = i->channel[ | |
| TORRENT_ASSERT(qe.max_block_size > 0); | | j]; | |
| m_queue.pop_front(); | | bwc->return_quota(i->assigned); | |
| | | } | |
| | | | |
|
| shared_ptr<Torrent> t = qe.torrent.lock(); | | i = m_queue.erase(i); | |
| if (!t) continue; | | | |
| if (qe.peer->is_disconnecting()) | | | |
| { | | | |
| l.unlock(); | | | |
| t->expire_bandwidth(m_channel, qe.max_block_ | | | |
| size); | | | |
| l.lock(); | | | |
| continue; | | continue; | |
| } | | } | |
|
| | | for (int j = 0; j < 5 && i->channel[j]; ++j) | |
| | | { | |
| | | bandwidth_channel* bwc = i->channel[j]; | |
| | | bwc->tmp = 0; | |
| | | } | |
| | | ++i; | |
| | | } | |
| | | | |
|
| // at this point, max_assignable may actually be zer | | for (typename queue_t::iterator i = m_queue.begin() | |
| o. Since | | , end(m_queue.end()); i != end; ++i) | |
| // the rate limit of the peer might have changed whi | | { | |
| le it | | for (int j = 0; j < 5 && i->channel[j]; ++j) | |
| // was in the queue. | | | |
| int max_assignable = qe.peer->max_assignable_bandwid | | | |
| th(m_channel); | | | |
| if (max_assignable == 0) | | | |
| { | | { | |
|
| TORRENT_ASSERT(is_in_history(qe.peer.get(), | | bandwidth_channel* bwc = i->channel[j]; | |
| l)); | | if (bwc->tmp == 0) channels.push_back(bwc); | |
| tmp.push_back(qe); | | bwc->tmp += i->priority; | |
| continue; | | TORRENT_ASSERT(i->priority > 0); | |
| } | | } | |
|
| | | } | |
| | | | |
|
| // this is the limit of the block size. It depends o | | for (std::vector<bandwidth_channel*>::iterator i = channels. | |
| n the throttle | | begin() | |
| // so that it can be closer to optimal. Larger block | | , end(channels.end()); i != end; ++i) | |
| sizes will give lower | | { | |
| // granularity to the rate but will be more efficien | | (*i)->update_quota(dt_milliseconds); | |
| t. At high rates | | } | |
| // the block sizes are bigger and at low rates, the | | | |
| granularity | | | |
| // is more important and block sizes are smaller | | | |
| | | | |
|
| // the minimum rate that can be given is the block s | | queue_t tm; | |
| ize, so, the | | | |
| // block size must be smaller for lower rates. This | | | |
| is because | | | |
| // the history window is one second, and the block w | | | |
| ill be forgotten | | | |
| // after one second. | | | |
| int block_size = (std::min)(qe.peer->bandwidth_throt | | | |
| tle(m_channel) | | | |
| , limit / 10); | | | |
| | | | |
|
| if (block_size < min_bandwidth_block_size) | | for (typename queue_t::iterator i = m_queue.begin(); | |
| { | | i != m_queue.end();) | |
| block_size = (std::min)(int(min_bandwidth_bl | | { | |
| ock_size), limit); | | int a = i->assign_bandwidth(); | |
| } | | if (i->assigned == i->request_size | |
| else if (block_size > max_bandwidth_block_size) | | || (i->ttl <= 0 && i->assigned > 0)) | |
| { | | { | |
|
| if (limit == bandwidth_limit::inf) | | a += i->request_size - i->assigned; | |
| { | | TORRENT_ASSERT(i->assigned <= i->request_siz | |
| block_size = max_bandwidth_block_siz | | e); | |
| e; | | tm.push_back(*i); | |
| } | | i = m_queue.erase(i); | |
| else | | | |
| { | | | |
| // try to make the block_size a divi | | | |
| sor of | | | |
| // m_limit to make the distributions | | | |
| as fair | | | |
| // as possible | | | |
| // TODO: move this calculcation to w | | | |
| here the limit | | | |
| // is changed | | | |
| block_size = limit | | | |
| / (limit / max_bandwidth_blo | | | |
| ck_size); | | | |
| } | | | |
| } | | } | |
|
| if (block_size > qe.max_block_size) block_size = qe. | | else | |
| max_block_size; | | | |
| | | | |
| if (amount < block_size / 4) | | | |
| { | | { | |
|
| tmp.push_back(qe); | | ++i; | |
| // m_queue.push_front(qe); | | | |
| break; | | | |
| } | | } | |
|
| | | m_queued_bytes -= a; | |
| | | } | |
| | | | |
|
| // so, hand out max_assignable, but no more than | | while (!tm.empty()) | |
| // the available bandwidth (amount) and no more | | { | |
| // than the max_bandwidth_block_size | | bw_request<PeerConnection>& bwr = tm.back(); | |
| int hand_out_amount = (std::min)((std::min)(block_si | | bwr.peer->assign_bandwidth(m_channel, bwr.assigned); | |
| ze, max_assignable) | | tm.pop_back(); | |
| , amount); | | | |
| TORRENT_ASSERT(hand_out_amount > 0); | | | |
| amount -= hand_out_amount; | | | |
| TORRENT_ASSERT(hand_out_amount <= qe.max_block_size) | | | |
| ; | | | |
| l.unlock(); | | | |
| t->assign_bandwidth(m_channel, hand_out_amount, qe.m | | | |
| ax_block_size); | | | |
| qe.peer->assign_bandwidth(m_channel, hand_out_amount | | | |
| ); | | | |
| l.lock(); | | | |
| add_history_entry(history_entry<PeerConnection, Torr | | | |
| ent>( | | | |
| qe.peer, t, hand_out_amount, now + bw_window | | | |
| _size)); | | | |
| } | | } | |
|
| if (!tmp.empty()) m_queue.insert(m_queue.begin(), tmp.begin(
), tmp.end()); | | | |
| } | | } | |
| | | | |
|
| typedef boost::mutex mutex_t; | | | |
| mutable mutex_t m_mutex; | | | |
| | | | |
| // the io_service used for the timer | | | |
| io_service& m_ios; | | | |
| | | | |
| // the timer that is waiting for the entries | | | |
| // in the history queue to expire (slide out | | | |
| // of the history window) | | | |
| deadline_timer m_history_timer; | | | |
| | | | |
| // the rate limit (bytes per second) | | | |
| int m_limit; | | | |
| | | | |
| // bytes to drain without handing out to a peer | | | |
| // used to deduct the IP overhead | | | |
| int m_drain_quota; | | | |
| | | | |
| // the sum of all recently handed out bandwidth blocks | | | |
| int m_current_quota; | | | |
| | | | |
| // these are the consumers that want bandwidth | | // these are the consumers that want bandwidth | |
|
| typedef std::deque<bw_queue_entry<PeerConnection, Torrent> > queue_t
; | | typedef std::vector<bw_request<PeerConnection> > queue_t; | |
| queue_t m_queue; | | queue_t m_queue; | |
|
| | | // the number of bytes all the requests in queue are for | |
| // these are the consumers that have received bandwidth | | int m_queued_bytes; | |
| // that will expire | | | |
| typedef std::deque<history_entry<PeerConnection, Torrent> > history_ | | | |
| t; | | | |
| history_t m_history; | | | |
| | | | |
| // this is the channel within the consumers | | // this is the channel within the consumers | |
| // that bandwidth is assigned to (upload or download) | | // that bandwidth is assigned to (upload or download) | |
| int m_channel; | | int m_channel; | |
| | | | |
|
| // this is true while we're in the hand_out_bandwidth loop | | | |
| // to prevent recursive invocations to interfere | | | |
| bool m_in_hand_out_bandwidth; | | | |
| | | | |
| bool m_abort; | | bool m_abort; | |
| | | | |
| #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | | #ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT | |
| std::ofstream m_log; | | std::ofstream m_log; | |
| ptime m_start; | | ptime m_start; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| | | | |
End of changes. 53 change blocks. |
| 386 lines changed or deleted | | 112 lines changed or added | |
|
| create_torrent.hpp | | create_torrent.hpp | |
| | | | |
| skipping to change at line 43 | | skipping to change at line 43 | |
| #ifndef TORRENT_CREATE_TORRENT_HPP_INCLUDED | | #ifndef TORRENT_CREATE_TORRENT_HPP_INCLUDED | |
| #define TORRENT_CREATE_TORRENT_HPP_INCLUDED | | #define TORRENT_CREATE_TORRENT_HPP_INCLUDED | |
| | | | |
| #include "libtorrent/bencode.hpp" | | #include "libtorrent/bencode.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
| #include "libtorrent/file_storage.hpp" | | #include "libtorrent/file_storage.hpp" | |
| #include "libtorrent/file_pool.hpp" | | #include "libtorrent/file_pool.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
| #include "libtorrent/hasher.hpp" | | #include "libtorrent/hasher.hpp" | |
|
| | | #include "libtorrent/utf8.hpp" | |
| | | #include "libtorrent/allocator.hpp" | |
| | | | |
| #include <vector> | | #include <vector> | |
| #include <string> | | #include <string> | |
| #include <utility> | | #include <utility> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/filesystem/path.hpp> | | #include <boost/filesystem/path.hpp> | |
| #include <boost/filesystem/operations.hpp> | | #include <boost/filesystem/operations.hpp> | |
| #include <boost/optional.hpp> | | #include <boost/optional.hpp> | |
|
| #include <boost/date_time/posix_time/posix_time.hpp> | | #include <boost/date_time/posix_time/posix_time_types.hpp> | |
| #include <boost/scoped_ptr.hpp> | | #include <boost/scoped_ptr.hpp> | |
|
| | | #include <boost/config.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| namespace pt = boost::posix_time; | | namespace pt = boost::posix_time; | |
|
| | | class torrent_info; | |
| | | | |
| struct TORRENT_EXPORT create_torrent | | struct TORRENT_EXPORT create_torrent | |
| { | | { | |
|
| create_torrent(file_storage& fs, int piece_size); | | enum { | |
| create_torrent(file_storage& fs); | | optimize = 1 | |
| | | , merkle = 2 | |
| | | , modification_time = 4 | |
| | | , symlinks = 8 | |
| | | }; | |
| | | | |
| | | create_torrent(file_storage& fs, int piece_size = 0 | |
| | | , int pad_file_limit = -1, int flags = optimize); | |
| | | create_torrent(torrent_info const& ti); | |
| entry generate() const; | | entry generate() const; | |
| | | | |
| file_storage const& files() const { return m_files; } | | file_storage const& files() const { return m_files; } | |
| | | | |
| void set_comment(char const* str); | | void set_comment(char const* str); | |
| void set_creator(char const* str); | | void set_creator(char const* str); | |
| void set_hash(int index, sha1_hash const& h); | | void set_hash(int index, sha1_hash const& h); | |
| void add_url_seed(std::string const& url); | | void add_url_seed(std::string const& url); | |
| void add_node(std::pair<std::string, int> const& node); | | void add_node(std::pair<std::string, int> const& node); | |
| void add_tracker(std::string const& url, int tier = 0); | | void add_tracker(std::string const& url, int tier = 0); | |
| void set_priv(bool p) { m_private = p; } | | void set_priv(bool p) { m_private = p; } | |
| | | | |
| int num_pieces() const { return m_files.num_pieces(); } | | int num_pieces() const { return m_files.num_pieces(); } | |
| int piece_length() const { return m_files.piece_length(); } | | int piece_length() const { return m_files.piece_length(); } | |
| int piece_size(int i) const { return m_files.piece_size(i);
} | | int piece_size(int i) const { return m_files.piece_size(i);
} | |
| bool priv() const { return m_private; } | | bool priv() const { return m_private; } | |
| | | | |
| private: | | private: | |
| | | | |
| file_storage& m_files; | | file_storage& m_files; | |
|
| | | // if m_info_dict is initialized, it is | |
| | | // used instead of m_files to generate | |
| | | // the info dictionary | |
| | | entry m_info_dict; | |
| | | | |
| // the urls to the trackers | | // the urls to the trackers | |
| typedef std::pair<std::string, int> announce_entry; | | typedef std::pair<std::string, int> announce_entry; | |
| std::vector<announce_entry> m_urls; | | std::vector<announce_entry> m_urls; | |
| | | | |
| std::vector<std::string> m_url_seeds; | | std::vector<std::string> m_url_seeds; | |
| | | | |
| std::vector<sha1_hash> m_piece_hash; | | std::vector<sha1_hash> m_piece_hash; | |
| | | | |
| // dht nodes to add to the routing table/bootstrap from | | // dht nodes to add to the routing table/bootstrap from | |
| | | | |
| skipping to change at line 127 | | skipping to change at line 143 | |
| | | | |
| // an optional string naming the software used | | // an optional string naming the software used | |
| // to create the torrent file | | // to create the torrent file | |
| std::string m_created_by; | | std::string m_created_by; | |
| | | | |
| // this is used when creating a torrent. If there's | | // this is used when creating a torrent. If there's | |
| // only one file there are cases where it's impossible | | // only one file there are cases where it's impossible | |
| // to know if it should be written as a multifile torrent | | // to know if it should be written as a multifile torrent | |
| // or not. e.g. test/test there's one file and one director
y | | // or not. e.g. test/test there's one file and one director
y | |
| // and they have the same name. | | // and they have the same name. | |
|
| bool m_multifile; | | bool m_multifile:1; | |
| | | | |
| // this is true if the torrent is private. i.e., is should n
ot | | // this is true if the torrent is private. i.e., is should n
ot | |
| // be announced on the dht | | // be announced on the dht | |
|
| bool m_private; | | bool m_private:1; | |
| | | | |
| | | // if set to one, a merkle torrent will be generated | |
| | | bool m_merkle_torrent:1; | |
| | | | |
| | | // if set, include the 'mtime' modification time in the | |
| | | // torrent file | |
| | | bool m_include_mtime:1; | |
| | | | |
| | | // if set, symbolic links are declared as such in | |
| | | // the torrent file. The full data of the pointed-to | |
| | | // file is still included | |
| | | bool m_include_symlinks:1; | |
| }; | | }; | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
| inline bool default_pred(boost::filesystem::path const&) { r
eturn true; } | | inline bool default_pred(boost::filesystem::path const&) { r
eturn true; } | |
|
| | | #if TORRENT_USE_WPATH | |
| | | inline bool wdefault_pred(boost::filesystem::wpath const&) { | |
| | | return true; } | |
| | | #endif | |
| | | | |
| | | inline bool ignore_subdir(std::string const& leaf) | |
| | | { return leaf == ".." || leaf == "."; } | |
| | | | |
| | | inline bool ignore_subdir(std::wstring const& leaf) | |
| | | { return leaf == L".." || leaf == L"."; } | |
| | | | |
| inline void nop(int i) {} | | inline void nop(int i) {} | |
| | | | |
|
| template <class Pred> | | int TORRENT_EXPORT get_file_attributes(boost::filesystem::pa | |
| void add_files_impl(file_storage& fs, boost::filesystem::pat | | th const& p); | |
| h const& p | | #if TORRENT_USE_WPATH | |
| , boost::filesystem::path const& l, Pred pred) | | int TORRENT_EXPORT get_file_attributes(boost::filesystem::wp | |
| | | ath const& p); | |
| | | #endif | |
| | | | |
| | | std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem: | |
| | | :path const& p); | |
| | | #if TORRENT_USE_WPATH | |
| | | std::time_t TORRENT_EXPORT get_file_mtime(boost::filesystem: | |
| | | :wpath const& p); | |
| | | #endif | |
| | | | |
| | | fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem:: | |
| | | path const& p); | |
| | | #if TORRENT_USE_WPATH | |
| | | fs::path TORRENT_EXPORT get_symlink_path(boost::filesystem:: | |
| | | wpath const& p); | |
| | | #endif | |
| | | | |
| | | template <class Pred, class Str, class PathTraits> | |
| | | void add_files_impl(file_storage& fs, boost::filesystem::bas | |
| | | ic_path<Str, PathTraits> const& p | |
| | | , boost::filesystem::basic_path<Str, PathTraits> con | |
| | | st& l, Pred pred) | |
| { | | { | |
|
| using boost::filesystem::path; | | using boost::filesystem::basic_path; | |
| using boost::filesystem::directory_iterator; | | using boost::filesystem::basic_directory_iterator; | |
| if (!pred(l)) return; | | basic_path<Str, PathTraits> f(p / l); | |
| path f(p / l); | | if (!pred(f)) return; | |
| if (is_directory(f)) | | if (is_directory(f)) | |
| { | | { | |
|
| for (directory_iterator i(f), end; i != end;
++i) | | for (basic_directory_iterator<basic_path<Str
, PathTraits> > i(f), end; i != end; ++i) | |
| { | | { | |
| #if BOOST_VERSION < 103600 | | #if BOOST_VERSION < 103600 | |
|
| std::string leaf = i->path().leaf(); | | Str const& leaf = i->path().leaf(); | |
| #else | | #else | |
|
| std::string leaf = i->path().filenam
e(); | | Str const& leaf = i->path().filename
(); | |
| #endif | | #endif | |
|
| if (leaf == ".." || leaf == ".") con
tinue; | | if (ignore_subdir(leaf)) continue; | |
| add_files_impl(fs, p, l / leaf, pred
); | | add_files_impl(fs, p, l / leaf, pred
); | |
| } | | } | |
| } | | } | |
| else | | else | |
| { | | { | |
|
| fs.add_file(l, file_size(f)); | | int file_flags = get_file_attributes(f); | |
| | | std::time_t mtime = get_file_mtime(f); | |
| | | //Masking all bits to check if the file is a | |
| | | symlink | |
| | | if(file_flags & file_storage::attribute_syml | |
| | | ink) | |
| | | { | |
| | | fs::path sym_path = get_symlink_path | |
| | | (f); | |
| | | fs.add_file(l, 0 ,file_flags, mtime, | |
| | | sym_path); | |
| | | } | |
| | | else | |
| | | { | |
| | | fs.add_file(l, file_size(f), file_fl | |
| | | ags, mtime); | |
| | | } | |
| } | | } | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | // path versions | |
| | | | |
| template <class Pred> | | template <class Pred> | |
| void add_files(file_storage& fs, boost::filesystem::path const& file
, Pred p) | | void add_files(file_storage& fs, boost::filesystem::path const& file
, Pred p) | |
| { | | { | |
|
| | | using boost::filesystem::path; | |
| boost::filesystem::path f = file; | | boost::filesystem::path f = file; | |
| #if BOOST_VERSION < 103600 | | #if BOOST_VERSION < 103600 | |
| if (f.leaf() == ".") f = f.branch_path(); | | if (f.leaf() == ".") f = f.branch_path(); | |
|
| detail::add_files_impl(fs, complete(f).branch_path(), f.leaf
(), p); | | detail::add_files_impl(fs, complete(f).branch_path(), path(f
.leaf()), p); | |
| #else | | #else | |
| if (f.filename() == ".") f = f.parent_path(); | | if (f.filename() == ".") f = f.parent_path(); | |
|
| detail::add_files_impl(fs, complete(f).parent_path(), f.file
name(), p); | | detail::add_files_impl(fs, complete(f).parent_path(), path(f
.filename()), p); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| inline void add_files(file_storage& fs, boost::filesystem::path cons
t& file) | | inline void add_files(file_storage& fs, boost::filesystem::path cons
t& file) | |
| { | | { | |
|
| | | using boost::filesystem::path; | |
| boost::filesystem::path f = file; | | boost::filesystem::path f = file; | |
| #if BOOST_VERSION < 103600 | | #if BOOST_VERSION < 103600 | |
| if (f.leaf() == ".") f = f.branch_path(); | | if (f.leaf() == ".") f = f.branch_path(); | |
|
| detail::add_files_impl(fs, complete(f).branch_path(), f.leaf
(), detail::default_pred); | | detail::add_files_impl(fs, complete(f).branch_path(), path(f
.leaf()), detail::default_pred); | |
| #else | | #else | |
| if (f.filename() == ".") f = f.parent_path(); | | if (f.filename() == ".") f = f.parent_path(); | |
|
| detail::add_files_impl(fs, complete(f).parent_path(), f.file
name(), detail::default_pred); | | detail::add_files_impl(fs, complete(f).parent_path(), path(f
.filename()), detail::default_pred); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| | | struct piece_holder | |
| | | { | |
| | | piece_holder(int bytes): m_piece(page_aligned_allocator::mal | |
| | | loc(bytes)) {} | |
| | | ~piece_holder() { page_aligned_allocator::free(m_piece); } | |
| | | char* bytes() { return m_piece; } | |
| | | private: | |
| | | char* m_piece; | |
| | | }; | |
| | | | |
| template <class Fun> | | template <class Fun> | |
| void set_piece_hashes(create_torrent& t, boost::filesystem::path con
st& p, Fun f | | void set_piece_hashes(create_torrent& t, boost::filesystem::path con
st& p, Fun f | |
| , error_code& ec) | | , error_code& ec) | |
| { | | { | |
| file_pool fp; | | file_pool fp; | |
| boost::scoped_ptr<storage_interface> st( | | boost::scoped_ptr<storage_interface> st( | |
| default_storage_constructor(const_cast<file_storage&
>(t.files()), 0, p, fp)); | | default_storage_constructor(const_cast<file_storage&
>(t.files()), 0, p, fp)); | |
| | | | |
| // calculate the hash for all pieces | | // calculate the hash for all pieces | |
| int num = t.num_pieces(); | | int num = t.num_pieces(); | |
|
| std::vector<char> buf(t.piece_length()); | | piece_holder buf(t.piece_length()); | |
| for (int i = 0; i < num; ++i) | | for (int i = 0; i < num; ++i) | |
| { | | { | |
| // read hits the disk and will block. Progress shoul
d | | // read hits the disk and will block. Progress shoul
d | |
| // be updated in between reads | | // be updated in between reads | |
|
| st->read(&buf[0], i, 0, t.piece_size(i)); | | st->read(buf.bytes(), i, 0, t.piece_size(i)); | |
| if (st->error()) | | if (st->error()) | |
| { | | { | |
| ec = st->error(); | | ec = st->error(); | |
| return; | | return; | |
| } | | } | |
|
| hasher h(&buf[0], t.piece_size(i)); | | hasher h(buf.bytes(), t.piece_size(i)); | |
| t.set_hash(i, h.final()); | | t.set_hash(i, h.final()); | |
| f(i); | | f(i); | |
| } | | } | |
| } | | } | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class Fun> | | template <class Fun> | |
| void set_piece_hashes(create_torrent& t, boost::filesystem::path con
st& p, Fun f) | | void set_piece_hashes(create_torrent& t, boost::filesystem::path con
st& p, Fun f) | |
| { | | { | |
| error_code ec; | | error_code ec; | |
| | | | |
| skipping to change at line 241 | | skipping to change at line 317 | |
| error_code ec; | | error_code ec; | |
| set_piece_hashes(t, p, detail::nop, ec); | | set_piece_hashes(t, p, detail::nop, ec); | |
| if (ec) throw libtorrent_exception(ec); | | if (ec) throw libtorrent_exception(ec); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| inline void set_piece_hashes(create_torrent& t, boost::filesystem::p
ath const& p, error_code& ec) | | inline void set_piece_hashes(create_torrent& t, boost::filesystem::p
ath const& p, error_code& ec) | |
| { | | { | |
| set_piece_hashes(t, p, detail::nop, ec); | | set_piece_hashes(t, p, detail::nop, ec); | |
| } | | } | |
|
| | | | |
| | | #if TORRENT_USE_WPATH | |
| | | // wpath versions | |
| | | | |
| | | template <class Pred> | |
| | | void add_files(file_storage& fs, boost::filesystem::wpath const& fil | |
| | | e, Pred p) | |
| | | { | |
| | | using boost::filesystem::wpath; | |
| | | wpath f = file; | |
| | | #if BOOST_VERSION < 103600 | |
| | | if (f.leaf() == L".") f = f.branch_path(); | |
| | | detail::add_files_impl(fs, complete(f).branch_path(), wpath( | |
| | | f.leaf()), p); | |
| | | #else | |
| | | if (f.filename() == L".") f = f.parent_path(); | |
| | | detail::add_files_impl(fs, complete(f).parent_path(), wpath( | |
| | | f.filename()), p); | |
| | | #endif | |
| | | } | |
| | | | |
| | | inline void add_files(file_storage& fs, boost::filesystem::wpath con | |
| | | st& file) | |
| | | { | |
| | | using boost::filesystem::wpath; | |
| | | wpath f = file; | |
| | | #if BOOST_VERSION < 103600 | |
| | | if (f.leaf() == L".") f = f.branch_path(); | |
| | | detail::add_files_impl(fs, complete(f).branch_path(), wpath( | |
| | | f.leaf()), detail::wdefault_pred); | |
| | | #else | |
| | | if (f.filename() == L".") f = f.parent_path(); | |
| | | detail::add_files_impl(fs, complete(f).parent_path(), wpath( | |
| | | f.filename()), detail::wdefault_pred); | |
| | | #endif | |
| | | } | |
| | | | |
| | | template <class Fun> | |
| | | void set_piece_hashes(create_torrent& t, boost::filesystem::wpath co | |
| | | nst& p, Fun f | |
| | | , error_code& ec) | |
| | | { | |
| | | file_pool fp; | |
| | | std::string utf8; | |
| | | wchar_utf8(p.string(), utf8); | |
| | | boost::scoped_ptr<storage_interface> st( | |
| | | default_storage_constructor(const_cast<file_storage& | |
| | | >(t.files()), 0, utf8, fp)); | |
| | | | |
| | | // calculate the hash for all pieces | |
| | | int num = t.num_pieces(); | |
| | | std::vector<char> buf(t.piece_length()); | |
| | | for (int i = 0; i < num; ++i) | |
| | | { | |
| | | // read hits the disk and will block. Progress shoul | |
| | | d | |
| | | // be updated in between reads | |
| | | st->read(&buf[0], i, 0, t.piece_size(i)); | |
| | | if (st->error()) | |
| | | { | |
| | | ec = st->error(); | |
| | | return; | |
| | | } | |
| | | hasher h(&buf[0], t.piece_size(i)); | |
| | | t.set_hash(i, h.final()); | |
| | | f(i); | |
| | | } | |
| | | } | |
| | | | |
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| | | template <class Fun> | |
| | | void set_piece_hashes(create_torrent& t, boost::filesystem::wpath co | |
| | | nst& p, Fun f) | |
| | | { | |
| | | error_code ec; | |
| | | set_piece_hashes(t, p, f, ec); | |
| | | if (ec) throw libtorrent_exception(ec); | |
| | | } | |
| | | | |
| | | inline void set_piece_hashes(create_torrent& t, boost::filesystem::w | |
| | | path const& p) | |
| | | { | |
| | | error_code ec; | |
| | | set_piece_hashes(t, p, detail::nop, ec); | |
| | | if (ec) throw libtorrent_exception(ec); | |
| | | } | |
| | | #endif | |
| | | | |
| | | inline void set_piece_hashes(create_torrent& t, boost::filesystem::w | |
| | | path const& p, error_code& ec) | |
| | | { | |
| | | set_piece_hashes(t, p, detail::nop, ec); | |
| | | } | |
| | | | |
| | | #endif // TORRENT_USE_WPATH | |
| | | | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 28 change blocks. |
| 25 lines changed or deleted | | 211 lines changed or added | |
|
| disk_io_thread.hpp | | disk_io_thread.hpp | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_DISK_IO_THREAD | | #ifndef TORRENT_DISK_IO_THREAD | |
| #define TORRENT_DISK_IO_THREAD | | #define TORRENT_DISK_IO_THREAD | |
| | | | |
|
| #ifdef TORRENT_DISK_STATS | | #if defined TORRENT_DISK_STATS || defined TORRENT_STATS | |
| #include <fstream> | | #include <fstream> | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
|
| | | #include "libtorrent/allocator.hpp" | |
| #include <boost/thread/thread.hpp> | | #include <boost/thread/thread.hpp> | |
| #include <boost/thread/mutex.hpp> | | #include <boost/thread/mutex.hpp> | |
| #include <boost/thread/condition.hpp> | | #include <boost/thread/condition.hpp> | |
| #include <boost/function.hpp> | | #include <boost/function.hpp> | |
| #include <boost/bind.hpp> | | #include <boost/bind.hpp> | |
| #include <boost/noncopyable.hpp> | | #include <boost/noncopyable.hpp> | |
| #include <boost/shared_array.hpp> | | #include <boost/shared_array.hpp> | |
| #include <list> | | #include <list> | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | | #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | |
| #include <boost/pool/pool.hpp> | | #include <boost/pool/pool.hpp> | |
| #endif | | #endif | |
|
| | | #include "libtorrent/session_settings.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| | | | |
| struct cached_piece_info | | struct cached_piece_info | |
| { | | { | |
| int piece; | | int piece; | |
| std::vector<bool> blocks; | | std::vector<bool> blocks; | |
| ptime last_use; | | ptime last_use; | |
| enum kind_t { read_cache = 0, write_cache = 1 }; | | enum kind_t { read_cache = 0, write_cache = 1 }; | |
| kind_t kind; | | kind_t kind; | |
| }; | | }; | |
| | | | |
| struct disk_io_job | | struct disk_io_job | |
| | | | |
| skipping to change at line 92 | | skipping to change at line 93 | |
| , move_storage | | , move_storage | |
| , release_files | | , release_files | |
| , delete_files | | , delete_files | |
| , check_fastresume | | , check_fastresume | |
| , check_files | | , check_files | |
| , save_resume_data | | , save_resume_data | |
| , rename_file | | , rename_file | |
| , abort_thread | | , abort_thread | |
| , clear_read_cache | | , clear_read_cache | |
| , abort_torrent | | , abort_torrent | |
|
| | | , update_settings | |
| | | , read_and_hash | |
| }; | | }; | |
| | | | |
| action_t action; | | action_t action; | |
| | | | |
| char* buffer; | | char* buffer; | |
| int buffer_size; | | int buffer_size; | |
| boost::intrusive_ptr<piece_manager> storage; | | boost::intrusive_ptr<piece_manager> storage; | |
| // arguments used for read and write | | // arguments used for read and write | |
| int piece, offset; | | int piece, offset; | |
| // used for move_storage and rename_file. On errors, this is
set | | // used for move_storage and rename_file. On errors, this is
set | |
| | | | |
| skipping to change at line 124 | | skipping to change at line 127 | |
| | | | |
| boost::shared_ptr<entry> resume_data; | | boost::shared_ptr<entry> resume_data; | |
| | | | |
| // the error code from the file operation | | // the error code from the file operation | |
| error_code error; | | error_code error; | |
| | | | |
| // this is called when operation completes | | // this is called when operation completes | |
| boost::function<void(int, disk_io_job const&)> callback; | | boost::function<void(int, disk_io_job const&)> callback; | |
| }; | | }; | |
| | | | |
|
| | | // returns true if the fundamental operation | |
| | | // of the given disk job is a read operation | |
| | | bool is_read_operation(disk_io_job const& j); | |
| | | | |
| | | // this is true if the buffer field in the disk_io_job | |
| | | // points to a disk buffer | |
| | | bool operation_has_buffer(disk_io_job const& j); | |
| | | | |
| struct cache_status | | struct cache_status | |
| { | | { | |
| cache_status() | | cache_status() | |
| : blocks_written(0) | | : blocks_written(0) | |
| , writes(0) | | , writes(0) | |
| , blocks_read(0) | | , blocks_read(0) | |
| , blocks_read_hit(0) | | , blocks_read_hit(0) | |
| , reads(0) | | , reads(0) | |
| , cache_size(0) | | , cache_size(0) | |
| , read_cache_size(0) | | , read_cache_size(0) | |
|
| | | , total_used_buffers(0) | |
| {} | | {} | |
| | | | |
| // the number of 16kB blocks written | | // the number of 16kB blocks written | |
| size_type blocks_written; | | size_type blocks_written; | |
| // the number of write operations used | | // the number of write operations used | |
| size_type writes; | | size_type writes; | |
| // (blocks_written - writes) / blocks_written represents the | | // (blocks_written - writes) / blocks_written represents the | |
| // "cache hit" ratio in the write cache | | // "cache hit" ratio in the write cache | |
| // the number of blocks read | | // the number of blocks read | |
| | | | |
| // the number of blocks passed back to the bittorrent engine | | // the number of blocks passed back to the bittorrent engine | |
| size_type blocks_read; | | size_type blocks_read; | |
| // the number of blocks that was just copied from the read c
ache | | // the number of blocks that was just copied from the read c
ache | |
| size_type blocks_read_hit; | | size_type blocks_read_hit; | |
| // the number of read operations used | | // the number of read operations used | |
| size_type reads; | | size_type reads; | |
| | | | |
|
| | | mutable size_type queued_bytes; | |
| | | | |
| // the number of blocks in the cache (both read and write) | | // the number of blocks in the cache (both read and write) | |
| int cache_size; | | int cache_size; | |
| | | | |
| // the number of blocks in the cache used for read cache | | // the number of blocks in the cache used for read cache | |
| int read_cache_size; | | int read_cache_size; | |
|
| | | | |
| | | // the total number of blocks that are currently in use | |
| | | // this includes send and receive buffers | |
| | | mutable int total_used_buffers; | |
| }; | | }; | |
| | | | |
|
| // this is a singleton consisting of the thread and a queue | | struct TORRENT_EXPORT disk_buffer_pool : boost::noncopyable | |
| // of disk io jobs | | | |
| struct disk_io_thread : boost::noncopyable | | | |
| { | | { | |
|
| disk_io_thread(io_service& ios, int block_size = 16 * 1024); | | disk_buffer_pool(int block_size); | |
| ~disk_io_thread(); | | #ifdef TORRENT_DEBUG | |
| | | ~disk_buffer_pool(); | |
| | | #endif | |
| | | | |
| | | #if defined TORRENT_DEBUG || defined TORRENT_DISK_STATS | |
| | | bool is_disk_buffer(char* buffer | |
| | | , boost::mutex::scoped_lock& l) const; | |
| | | bool is_disk_buffer(char* buffer) const; | |
| | | #endif | |
| | | | |
| | | char* allocate_buffer(char const* category); | |
| | | void free_buffer(char* buf); | |
| | | | |
| | | char* allocate_buffers(int blocks, char const* category); | |
| | | void free_buffers(char* buf, int blocks); | |
| | | | |
| | | int block_size() const { return m_block_size; } | |
| | | | |
| #ifdef TORRENT_STATS | | #ifdef TORRENT_STATS | |
| int disk_allocations() const | | int disk_allocations() const | |
| { return m_allocations; } | | { return m_allocations; } | |
| #endif | | #endif | |
| | | | |
|
| | | #ifdef TORRENT_DISK_STATS | |
| | | std::ofstream m_disk_access_log; | |
| | | #endif | |
| | | | |
| | | void release_memory(); | |
| | | | |
| | | int in_use() const { return m_in_use; } | |
| | | | |
| | | protected: | |
| | | | |
| | | // number of bytes per block. The BitTorrent | |
| | | // protocol defines the block size to 16 KiB. | |
| | | const int m_block_size; | |
| | | | |
| | | // number of disk buffers currently allocated | |
| | | int m_in_use; | |
| | | | |
| | | session_settings m_settings; | |
| | | | |
| | | private: | |
| | | | |
| | | // this only protects the pool allocator | |
| | | typedef boost::mutex mutex_t; | |
| | | mutable mutex_t m_pool_mutex; | |
| | | #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | |
| | | // memory pool for read and write operations | |
| | | // and disk cache | |
| | | boost::pool<page_aligned_allocator> m_pool; | |
| | | #endif | |
| | | | |
| | | #if defined TORRENT_DISK_STATS || defined TORRENT_STATS | |
| | | int m_allocations; | |
| | | #endif | |
| | | #ifdef TORRENT_DISK_STATS | |
| | | public: | |
| | | void rename_buffer(char* buf, char const* category); | |
| | | protected: | |
| | | std::map<std::string, int> m_categories; | |
| | | std::map<char*, std::string> m_buf_to_category; | |
| | | std::ofstream m_log; | |
| | | private: | |
| | | #endif | |
| | | #ifdef TORRENT_DEBUG | |
| | | int m_magic; | |
| | | #endif | |
| | | }; | |
| | | | |
| | | // this is a singleton consisting of the thread and a queue | |
| | | // of disk io jobs | |
| | | struct TORRENT_EXPORT disk_io_thread : disk_buffer_pool | |
| | | { | |
| | | disk_io_thread(io_service& ios | |
| | | , boost::function<void()> const& queue_callback | |
| | | , file_pool& fp | |
| | | , int block_size = 16 * 1024); | |
| | | ~disk_io_thread(); | |
| | | | |
| void join(); | | void join(); | |
| | | | |
| // aborts read operations | | // aborts read operations | |
| void stop(boost::intrusive_ptr<piece_manager> s); | | void stop(boost::intrusive_ptr<piece_manager> s); | |
| void add_job(disk_io_job const& j | | void add_job(disk_io_job const& j | |
| , boost::function<void(int, disk_io_job const&)> con
st& f | | , boost::function<void(int, disk_io_job const&)> con
st& f | |
| = boost::function<void(int, disk_io_job const&)>()); | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
| // keep track of the number of bytes in the job queue | | // keep track of the number of bytes in the job queue | |
| // at any given time. i.e. the sum of all buffer_size. | | // at any given time. i.e. the sum of all buffer_size. | |
| // this is used to slow down the download global download | | // this is used to slow down the download global download | |
| // speed when the queue buffer size is too big. | | // speed when the queue buffer size is too big. | |
|
| size_type queue_buffer_size() const | | size_type queue_buffer_size() const; | |
| { return m_queue_buffer_size; } | | | |
| | | | |
| void get_cache_info(sha1_hash const& ih | | void get_cache_info(sha1_hash const& ih | |
| , std::vector<cached_piece_info>& ret) const; | | , std::vector<cached_piece_info>& ret) const; | |
| | | | |
| cache_status status() const; | | cache_status status() const; | |
|
| void set_cache_size(int s); | | | |
| void set_cache_expiry(int ex); | | | |
| | | | |
| void operator()(); | | void operator()(); | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
|
| bool is_disk_buffer(char* buffer) const; | | | |
| #endif | | | |
| | | | |
| char* allocate_buffer(); | | | |
| void free_buffer(char* buf); | | | |
| | | | |
| #ifdef TORRENT_DEBUG | | | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
|
| private: | | struct cached_block_entry | |
| | | { | |
| | | cached_block_entry(): buf(0) {} | |
| | | // the buffer pointer (this is a disk_pool buffer) | |
| | | // or 0 | |
| | | char* buf; | |
| | | | |
| | | // callback for when this block is flushed to disk | |
| | | boost::function<void(int, disk_io_job const&)> callb | |
| | | ack; | |
| | | }; | |
| | | | |
| struct cached_piece_entry | | struct cached_piece_entry | |
| { | | { | |
| int piece; | | int piece; | |
| // storage this piece belongs to | | // storage this piece belongs to | |
| boost::intrusive_ptr<piece_manager> storage; | | boost::intrusive_ptr<piece_manager> storage; | |
| // the last time a block was writting to this piece | | // the last time a block was writting to this piece | |
| ptime last_use; | | ptime last_use; | |
| // the number of blocks in the cache for this piece | | // the number of blocks in the cache for this piece | |
| int num_blocks; | | int num_blocks; | |
| // the pointers to the block data | | // the pointers to the block data | |
|
| boost::shared_array<char*> blocks; | | boost::shared_array<cached_block_entry> blocks; | |
| }; | | }; | |
| | | | |
| typedef boost::recursive_mutex mutex_t; | | typedef boost::recursive_mutex mutex_t; | |
|
| | | | |
| | | // TODO: turn this into a multi-index list | |
| | | // sorted by piece and last use time | |
| typedef std::list<cached_piece_entry> cache_t; | | typedef std::list<cached_piece_entry> cache_t; | |
| | | | |
|
| | | private: | |
| | | | |
| bool test_error(disk_io_job& j); | | bool test_error(disk_io_job& j); | |
| void post_callback(boost::function<void(int, disk_io_job con
st&)> const& handler | | void post_callback(boost::function<void(int, disk_io_job con
st&)> const& handler | |
| , disk_io_job const& j, int ret); | | , disk_io_job const& j, int ret); | |
| | | | |
| // cache operations | | // cache operations | |
| cache_t::iterator find_cached_piece( | | cache_t::iterator find_cached_piece( | |
| cache_t& cache, disk_io_job const& j | | cache_t& cache, disk_io_job const& j | |
| , mutex_t::scoped_lock& l); | | , mutex_t::scoped_lock& l); | |
|
| | | bool is_cache_hit(cache_t::iterator p | |
| | | , disk_io_job const& j, mutex_t::scoped_lock& l); | |
| | | int copy_from_piece(cache_t::iterator p, bool& hit | |
| | | , disk_io_job const& j, mutex_t::scoped_lock& l); | |
| | | | |
| // write cache operations | | // write cache operations | |
|
| void flush_oldest_piece(mutex_t::scoped_lock& l); | | enum options_t { dont_flush_write_blocks = 1, ignore_cache_s | |
| | | ize = 2 }; | |
| | | int flush_cache_blocks(mutex_t::scoped_lock& l | |
| | | , int blocks, cache_t::iterator ignore | |
| | | , int options = 0); | |
| void flush_expired_pieces(); | | void flush_expired_pieces(); | |
|
| void flush_and_remove(cache_t::iterator i, mutex_t::scoped_l | | int flush_and_remove(cache_t::iterator i, mutex_t::scoped_lo | |
| ock& l); | | ck& l); | |
| void flush(cache_t::iterator i, mutex_t::scoped_lock& l); | | int flush_contiguous_blocks(disk_io_thread::cache_t::iterato | |
| int cache_block(disk_io_job& j, mutex_t::scoped_lock& l); | | r e | |
| | | , mutex_t::scoped_lock& l, int lower_limit = 0); | |
| | | int flush_range(cache_t::iterator i, int start, int end, mut | |
| | | ex_t::scoped_lock& l); | |
| | | int cache_block(disk_io_job& j | |
| | | , boost::function<void(int,disk_io_job const&)>& han | |
| | | dler | |
| | | , mutex_t::scoped_lock& l); | |
| | | | |
| // read cache operations | | // read cache operations | |
|
| bool clear_oldest_read_piece(cache_t::iterator ignore | | int clear_oldest_read_piece(int num_blocks, cache_t::iterato
r ignore | |
| , mutex_t::scoped_lock& l); | | , mutex_t::scoped_lock& l); | |
|
| int read_into_piece(cached_piece_entry& p, int start_block, | | int read_into_piece(cached_piece_entry& p, int start_block | |
| mutex_t::scoped_lock& l); | | , int options, int num_blocks, mutex_t::scoped_lock& | |
| | | l); | |
| int cache_read_block(disk_io_job const& j, mutex_t::scoped_l
ock& l); | | int cache_read_block(disk_io_job const& j, mutex_t::scoped_l
ock& l); | |
|
| void free_piece(cached_piece_entry& p, mutex_t::scoped_lock& | | int cache_read_piece(disk_io_job const& j, mutex_t::scoped_l | |
| l); | | ock& l); | |
| bool make_room(int num_blocks | | int free_piece(cached_piece_entry& p, mutex_t::scoped_lock& | |
| , cache_t::iterator ignore | | l); | |
| , mutex_t::scoped_lock& l); | | | |
| int try_read_from_cache(disk_io_job const& j); | | int try_read_from_cache(disk_io_job const& j); | |
|
| | | int read_piece_from_cache_and_hash(disk_io_job const& j, sha
1_hash& h); | |
| | | | |
| // this mutex only protects m_jobs, m_queue_buffer_size | | // this mutex only protects m_jobs, m_queue_buffer_size | |
| // and m_abort | | // and m_abort | |
| mutable mutex_t m_queue_mutex; | | mutable mutex_t m_queue_mutex; | |
| boost::condition m_signal; | | boost::condition m_signal; | |
| bool m_abort; | | bool m_abort; | |
|
| | | bool m_waiting_to_shutdown; | |
| std::list<disk_io_job> m_jobs; | | std::list<disk_io_job> m_jobs; | |
| size_type m_queue_buffer_size; | | size_type m_queue_buffer_size; | |
| | | | |
|
| | | ptime m_last_file_check; | |
| | | | |
| // this protects the piece cache and related members | | // this protects the piece cache and related members | |
| mutable mutex_t m_piece_mutex; | | mutable mutex_t m_piece_mutex; | |
| // write cache | | // write cache | |
| cache_t m_pieces; | | cache_t m_pieces; | |
| | | | |
| // read cache | | // read cache | |
| cache_t m_read_pieces; | | cache_t m_read_pieces; | |
| | | | |
| // total number of blocks in use by both the read | | // total number of blocks in use by both the read | |
| // and the write cache. This is not supposed to | | // and the write cache. This is not supposed to | |
| // exceed m_cache_size | | // exceed m_cache_size | |
| cache_status m_cache_stats; | | cache_status m_cache_stats; | |
| | | | |
|
| // in (16kB) blocks | | | |
| int m_cache_size; | | | |
| | | | |
| // expiration time of cache entries in seconds | | | |
| int m_cache_expiry; | | | |
| | | | |
| // if set to true, each piece flush will allocate | | | |
| // one piece worth of temporary memory on the heap | | | |
| // and copy the block data into it, and then perform | | | |
| // a single write operation from that buffer. | | | |
| // if memory is constrained, that temporary buffer | | | |
| // might is avoided by setting this to false. | | | |
| // in case the allocation fails, the piece flush | | | |
| // falls back to writing each block separately. | | | |
| bool m_coalesce_writes; | | | |
| bool m_coalesce_reads; | | | |
| bool m_use_read_cache; | | | |
| | | | |
| // this only protects the pool allocator | | | |
| mutable mutex_t m_pool_mutex; | | | |
| #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | | | |
| // memory pool for read and write operations | | | |
| // and disk cache | | | |
| boost::pool<> m_pool; | | | |
| #endif | | | |
| | | | |
| // number of bytes per block. The BitTorrent | | | |
| // protocol defines the block size to 16 KiB. | | | |
| int m_block_size; | | | |
| | | | |
| #ifdef TORRENT_DISK_STATS | | #ifdef TORRENT_DISK_STATS | |
| std::ofstream m_log; | | std::ofstream m_log; | |
| #endif | | #endif | |
|
| #ifdef TORRENT_STATS | | | |
| int m_allocations; | | | |
| #endif | | | |
| | | | |
| size_type m_writes; | | | |
| size_type m_blocks_written; | | | |
| | | | |
| io_service& m_ios; | | io_service& m_ios; | |
| | | | |
|
| | | boost::function<void()> m_queue_callback; | |
| | | | |
| // this keeps the io_service::run() call blocked from | | // this keeps the io_service::run() call blocked from | |
| // returning. When shutting down, it's possible that | | // returning. When shutting down, it's possible that | |
| // the event queue is drained before the disk_io_thread | | // the event queue is drained before the disk_io_thread | |
| // has posted its last callback. When this happens, the | | // has posted its last callback. When this happens, the | |
| // io_service will have a pending callback from the | | // io_service will have a pending callback from the | |
| // disk_io_thread, but the event loop is not running. | | // disk_io_thread, but the event loop is not running. | |
| // this means that the event is destructed after the | | // this means that the event is destructed after the | |
| // disk_io_thread. If the event refers to a disk buffer | | // disk_io_thread. If the event refers to a disk buffer | |
| // it will try to free it, but the buffer pool won't | | // it will try to free it, but the buffer pool won't | |
| // exist anymore, and crash. This prevents that. | | // exist anymore, and crash. This prevents that. | |
| boost::optional<asio::io_service::work> m_work; | | boost::optional<asio::io_service::work> m_work; | |
| | | | |
|
| | | // reference to the file_pool which is a member of | |
| | | // the session_impl object | |
| | | file_pool& m_file_pool; | |
| | | | |
| // thread for performing blocking disk io operations | | // thread for performing blocking disk io operations | |
| boost::thread m_disk_io_thread; | | boost::thread m_disk_io_thread; | |
|
| #ifdef TORRENT_DEBUG | | | |
| int m_magic; | | | |
| #endif | | | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif | | #endif | |
| | | | |
End of changes. 33 change blocks. |
| 72 lines changed or deleted | | 152 lines changed or added | |
|
| entry.hpp | | entry.hpp | |
| | | | |
| skipping to change at line 61 | | skipping to change at line 61 | |
| * are asking for, otherwise you will get an | | * are asking for, otherwise you will get an | |
| * assertion failure. | | * assertion failure. | |
| * When you default construct an entry, it is | | * When you default construct an entry, it is | |
| * uninitialized. You can initialize it through the | | * uninitialized. You can initialize it through the | |
| * assignment operator, copy-constructor or | | * assignment operator, copy-constructor or | |
| * the constructor that takes a data_type enum. | | * the constructor that takes a data_type enum. | |
| * | | * | |
| * | | * | |
| */ | | */ | |
| | | | |
|
| #include <iosfwd> | | | |
| #include <map> | | #include <map> | |
| #include <list> | | #include <list> | |
| #include <string> | | #include <string> | |
| #include <stdexcept> | | #include <stdexcept> | |
| | | | |
| #include "libtorrent/size_type.hpp" | | #include "libtorrent/size_type.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
|
| | | #include "libtorrent/error_code.hpp" | |
| | | | |
| | | #if TORRENT_USE_IOSTREAM | |
| | | #include <iosfwd> | |
| | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| | | struct lazy_entry; | |
| | | | |
| struct TORRENT_EXPORT type_error: std::runtime_error | | struct TORRENT_EXPORT type_error: std::runtime_error | |
| { | | { | |
| type_error(const char* error): std::runtime_error(error) {} | | type_error(const char* error): std::runtime_error(error) {} | |
| }; | | }; | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
| template<int v1, int v2> | | template<int v1, int v2> | |
| struct max2 { enum { value = v1>v2?v1:v2 }; }; | | struct max2 { enum { value = v1>v2?v1:v2 }; }; | |
| | | | |
| skipping to change at line 142 | | skipping to change at line 147 | |
| entry(list_type const&); | | entry(list_type const&); | |
| entry(integer_type const&); | | entry(integer_type const&); | |
| | | | |
| entry(); | | entry(); | |
| entry(data_type t); | | entry(data_type t); | |
| entry(entry const& e); | | entry(entry const& e); | |
| ~entry(); | | ~entry(); | |
| | | | |
| bool operator==(entry const& e) const; | | bool operator==(entry const& e) const; | |
| | | | |
|
| | | void operator=(lazy_entry const&); | |
| void operator=(entry const&); | | void operator=(entry const&); | |
| void operator=(dictionary_type const&); | | void operator=(dictionary_type const&); | |
| void operator=(string_type const&); | | void operator=(string_type const&); | |
| void operator=(list_type const&); | | void operator=(list_type const&); | |
| void operator=(integer_type const&); | | void operator=(integer_type const&); | |
| | | | |
| integer_type& integer(); | | integer_type& integer(); | |
| const integer_type& integer() const; | | const integer_type& integer() const; | |
| string_type& string(); | | string_type& string(); | |
| const string_type& string() const; | | const string_type& string() const; | |
| | | | |
| skipping to change at line 172 | | skipping to change at line 178 | |
| entry& operator[](std::string const& key); | | entry& operator[](std::string const& key); | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
| const entry& operator[](char const* key) const; | | const entry& operator[](char const* key) const; | |
| const entry& operator[](std::string const& key) const; | | const entry& operator[](std::string const& key) const; | |
| #endif | | #endif | |
| entry* find_key(char const* key); | | entry* find_key(char const* key); | |
| entry const* find_key(char const* key) const; | | entry const* find_key(char const* key) const; | |
| entry* find_key(std::string const& key); | | entry* find_key(std::string const& key); | |
| entry const* find_key(std::string const& key) const; | | entry const* find_key(std::string const& key) const; | |
| | | | |
|
| | | #if (defined TORRENT_VERBOSE_LOGGING || defined TORRENT_DEBUG) && TORRENT_U
SE_IOSTREAM | |
| void print(std::ostream& os, int indent = 0) const; | | void print(std::ostream& os, int indent = 0) const; | |
|
| | | #endif | |
| | | | |
| protected: | | protected: | |
| | | | |
| void construct(data_type t); | | void construct(data_type t); | |
| void copy(const entry& e); | | void copy(const entry& e); | |
| void destruct(); | | void destruct(); | |
| | | | |
| private: | | private: | |
| | | | |
| data_type m_type; | | data_type m_type; | |
| | | | |
| skipping to change at line 220 | | skipping to change at line 228 | |
| // in debug mode this is set to false by bdecode | | // in debug mode this is set to false by bdecode | |
| // to indicate that the program has not yet queried | | // to indicate that the program has not yet queried | |
| // the type of this entry, and sould not assume | | // the type of this entry, and sould not assume | |
| // that it has a certain type. This is asserted in | | // that it has a certain type. This is asserted in | |
| // the accessor functions. This does not apply if | | // the accessor functions. This does not apply if | |
| // exceptions are used. | | // exceptions are used. | |
| mutable bool m_type_queried; | | mutable bool m_type_queried; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
|
| | | #if defined TORRENT_DEBUG && TORRENT_USE_IOSTREAM | |
| inline std::ostream& operator<<(std::ostream& os, const entry& e) | | inline std::ostream& operator<<(std::ostream& os, const entry& e) | |
| { | | { | |
| e.print(os, 0); | | e.print(os, 0); | |
| return os; | | return os; | |
| } | | } | |
|
| | | #endif | |
| | | | |
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| | | inline void throw_type_error() | |
| | | { | |
| | | throw libtorrent_exception(error_code(errors::invalid_entry_ | |
| | | type | |
| | | , get_libtorrent_category())); | |
| | | } | |
| | | #endif | |
| | | | |
| inline entry::data_type entry::type() const | | inline entry::data_type entry::type() const | |
| { | | { | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| m_type_queried = true; | | m_type_queried = true; | |
| #endif | | #endif | |
| return m_type; | | return m_type; | |
| } | | } | |
| | | | |
| inline entry::~entry() { destruct(); } | | inline entry::~entry() { destruct(); } | |
| | | | |
| skipping to change at line 246 | | skipping to change at line 264 | |
| inline void entry::operator=(const entry& e) | | inline void entry::operator=(const entry& e) | |
| { | | { | |
| destruct(); | | destruct(); | |
| copy(e); | | copy(e); | |
| } | | } | |
| | | | |
| inline entry::integer_type& entry::integer() | | inline entry::integer_type& entry::integer() | |
| { | | { | |
| if (m_type == undefined_t) construct(int_t); | | if (m_type == undefined_t) construct(int_t); | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != int_t) throw type_error("invalid type requeste
d from entry"); | | if (m_type != int_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == int_t); | | TORRENT_ASSERT(m_type == int_t); | |
| return *reinterpret_cast<integer_type*>(data); | | return *reinterpret_cast<integer_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::integer_type const& entry::integer() const | | inline entry::integer_type const& entry::integer() const | |
| { | | { | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != int_t) throw type_error("invalid type requeste
d from entry"); | | if (m_type != int_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == int_t); | | TORRENT_ASSERT(m_type == int_t); | |
| return *reinterpret_cast<const integer_type*>(data); | | return *reinterpret_cast<const integer_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::string_type& entry::string() | | inline entry::string_type& entry::string() | |
| { | | { | |
| if (m_type == undefined_t) construct(string_t); | | if (m_type == undefined_t) construct(string_t); | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != string_t) throw type_error("invalid type reque
sted from entry"); | | if (m_type != string_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == string_t); | | TORRENT_ASSERT(m_type == string_t); | |
| return *reinterpret_cast<string_type*>(data); | | return *reinterpret_cast<string_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::string_type const& entry::string() const | | inline entry::string_type const& entry::string() const | |
| { | | { | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != string_t) throw type_error("invalid type reque
sted from entry"); | | if (m_type != string_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == string_t); | | TORRENT_ASSERT(m_type == string_t); | |
| return *reinterpret_cast<const string_type*>(data); | | return *reinterpret_cast<const string_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::list_type& entry::list() | | inline entry::list_type& entry::list() | |
| { | | { | |
| if (m_type == undefined_t) construct(list_t); | | if (m_type == undefined_t) construct(list_t); | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != list_t) throw type_error("invalid type request
ed from entry"); | | if (m_type != list_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == list_t); | | TORRENT_ASSERT(m_type == list_t); | |
| return *reinterpret_cast<list_type*>(data); | | return *reinterpret_cast<list_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::list_type const& entry::list() const | | inline entry::list_type const& entry::list() const | |
| { | | { | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != list_t) throw type_error("invalid type request
ed from entry"); | | if (m_type != list_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == list_t); | | TORRENT_ASSERT(m_type == list_t); | |
| return *reinterpret_cast<const list_type*>(data); | | return *reinterpret_cast<const list_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::dictionary_type& entry::dict() | | inline entry::dictionary_type& entry::dict() | |
| { | | { | |
| if (m_type == undefined_t) construct(dictionary_t); | | if (m_type == undefined_t) construct(dictionary_t); | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != dictionary_t) throw type_error("invalid type r
equested from entry"); | | if (m_type != dictionary_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == dictionary_t); | | TORRENT_ASSERT(m_type == dictionary_t); | |
| return *reinterpret_cast<dictionary_type*>(data); | | return *reinterpret_cast<dictionary_type*>(data); | |
| } | | } | |
| | | | |
| inline entry::dictionary_type const& entry::dict() const | | inline entry::dictionary_type const& entry::dict() const | |
| { | | { | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| if (m_type != dictionary_t) throw type_error("invalid type r
equested from entry"); | | if (m_type != dictionary_t) throw_type_error(); | |
| #elif defined TORRENT_DEBUG | | #elif defined TORRENT_DEBUG | |
| TORRENT_ASSERT(m_type_queried); | | TORRENT_ASSERT(m_type_queried); | |
| #endif | | #endif | |
| TORRENT_ASSERT(m_type == dictionary_t); | | TORRENT_ASSERT(m_type == dictionary_t); | |
| return *reinterpret_cast<const dictionary_type*>(data); | | return *reinterpret_cast<const dictionary_type*>(data); | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_ENTRY_HPP_INCLUDED | | #endif // TORRENT_ENTRY_HPP_INCLUDED | |
| | | | |
End of changes. 16 change blocks. |
| 9 lines changed or deleted | | 28 lines changed or added | |
|
| peer_connection.hpp | | peer_connection.hpp | |
| | | | |
| skipping to change at line 39 | | skipping to change at line 39 | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_PEER_CONNECTION_HPP_INCLUDED | | #ifndef TORRENT_PEER_CONNECTION_HPP_INCLUDED | |
| #define TORRENT_PEER_CONNECTION_HPP_INCLUDED | | #define TORRENT_PEER_CONNECTION_HPP_INCLUDED | |
| | | | |
| #include <ctime> | | #include <ctime> | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
|
| #include <deque> | | | |
| #include <string> | | #include <string> | |
| | | | |
| #include "libtorrent/debug.hpp" | | #include "libtorrent/debug.hpp" | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/smart_ptr.hpp> | | #include <boost/smart_ptr.hpp> | |
| #include <boost/weak_ptr.hpp> | | #include <boost/weak_ptr.hpp> | |
| #include <boost/noncopyable.hpp> | | #include <boost/noncopyable.hpp> | |
| #include <boost/array.hpp> | | #include <boost/array.hpp> | |
| #include <boost/optional.hpp> | | #include <boost/optional.hpp> | |
| #include <boost/cstdint.hpp> | | #include <boost/cstdint.hpp> | |
| #include <boost/pool/pool.hpp> | | #include <boost/pool/pool.hpp> | |
|
| | | #include <boost/aligned_storage.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/buffer.hpp" | | #include "libtorrent/buffer.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
| | | | |
| skipping to change at line 97 | | skipping to change at line 97 | |
| class torrent; | | class torrent; | |
| struct peer_plugin; | | struct peer_plugin; | |
| | | | |
| namespace detail | | namespace detail | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
| } | | } | |
| | | | |
| struct pending_block | | struct pending_block | |
| { | | { | |
|
| pending_block(piece_block const& b): skipped(0), block(b) {} | | pending_block(piece_block const& b) | |
| int skipped; | | : skipped(0), not_wanted(false), timed_out(false) | |
| | | , busy(false), block(b) {} | |
| | | | |
| // the number of times the request | | // the number of times the request | |
| // has been skipped by out of order blocks | | // has been skipped by out of order blocks | |
|
| | | boost::uint16_t skipped; | |
| | | | |
| | | // if any of these are set to true, this block | |
| | | // is not allocated | |
| | | // in the piece picker anymore, and open for | |
| | | // other peers to pick. This may be caused by | |
| | | // it either timing out or being received | |
| | | // unexpectedly from the peer | |
| | | bool not_wanted:1; | |
| | | bool timed_out:1; | |
| | | | |
| | | // the busy flag is set if the block was | |
| | | // requested from another peer when this | |
| | | // request was queued. We only allow a single | |
| | | // busy request at a time in each peer's queue | |
| | | bool busy:1; | |
| | | | |
| piece_block block; | | piece_block block; | |
| | | | |
| bool operator==(pending_block const& b) | | bool operator==(pending_block const& b) | |
|
| { return b.skipped == skipped && b.block == block; } | | { | |
| | | return b.skipped == skipped && b.block == block | |
| | | && b.not_wanted == not_wanted && b.timed_out | |
| | | == timed_out; | |
| | | } | |
| }; | | }; | |
| | | | |
| struct has_block | | struct has_block | |
| { | | { | |
| has_block(piece_block const& b): block(b) {} | | has_block(piece_block const& b): block(b) {} | |
| piece_block const& block; | | piece_block const& block; | |
| bool operator()(pending_block const& pb) const | | bool operator()(pending_block const& pb) const | |
| { return pb.block == block; } | | { return pb.block == block; } | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 211 | | skipping to change at line 233 | |
| | | | |
| void prefer_whole_pieces(int num) | | void prefer_whole_pieces(int num) | |
| { m_prefer_whole_pieces = num; } | | { m_prefer_whole_pieces = num; } | |
| | | | |
| bool request_large_blocks() const | | bool request_large_blocks() const | |
| { return m_request_large_blocks; } | | { return m_request_large_blocks; } | |
| | | | |
| void request_large_blocks(bool b) | | void request_large_blocks(bool b) | |
| { m_request_large_blocks = b; } | | { m_request_large_blocks = b; } | |
| | | | |
|
| | | bool no_download() const { return m_no_download; } | |
| | | void no_download(bool b) { m_no_download = b; } | |
| | | | |
| void set_priority(int p) | | void set_priority(int p) | |
|
| { m_priority = p; } | | { | |
| | | TORRENT_ASSERT(p > 0); | |
| | | TORRENT_ASSERT(m_priority <= 255); | |
| | | if (p > 255) p = 255; | |
| | | m_priority = p; | |
| | | } | |
| | | | |
| void fast_reconnect(bool r); | | void fast_reconnect(bool r); | |
| bool fast_reconnect() const { return m_fast_reconnect; } | | bool fast_reconnect() const { return m_fast_reconnect; } | |
| | | | |
| // this adds an announcement in the announcement queue | | // this adds an announcement in the announcement queue | |
| // it will let the peer know that we have the given piece | | // it will let the peer know that we have the given piece | |
| void announce_piece(int index); | | void announce_piece(int index); | |
| | | | |
|
| | | // this will tell the peer to announce the given piece | |
| | | // and only allow it to request that piece | |
| | | void superseed_piece(int index); | |
| | | int superseed_piece() const { return m_superseed_piece; } | |
| | | | |
| // tells if this connection has data it want to send | | // tells if this connection has data it want to send | |
| // and has enough upload bandwidth quota left to send it. | | // and has enough upload bandwidth quota left to send it. | |
| bool can_write() const; | | bool can_write() const; | |
|
| bool can_read() const; | | bool can_read(char* state = 0) const; | |
| | | | |
| bool is_seed() const; | | bool is_seed() const; | |
| | | | |
|
| void set_upload_only(bool u) | | void set_upload_only(bool u); | |
| { | | | |
| m_upload_only = u; | | | |
| disconnect_if_redundant(); | | | |
| } | | | |
| | | | |
| bool upload_only() const { return m_upload_only; } | | bool upload_only() const { return m_upload_only; } | |
| | | | |
| // will send a keep-alive message to the peer | | // will send a keep-alive message to the peer | |
| void keep_alive(); | | void keep_alive(); | |
| | | | |
| peer_id const& pid() const { return m_peer_id; } | | peer_id const& pid() const { return m_peer_id; } | |
|
| void set_pid(const peer_id& pid) { m_peer_id = pid; } | | void set_pid(const peer_id& peer_id) { m_peer_id = peer_id;
} | |
| bool has_piece(int i) const; | | bool has_piece(int i) const; | |
| | | | |
|
| std::deque<pending_block> const& download_queue() const; | | std::vector<pending_block> const& download_queue() const; | |
| std::deque<piece_block> const& request_queue() const; | | std::vector<pending_block> const& request_queue() const; | |
| std::deque<peer_request> const& upload_queue() const; | | std::vector<peer_request> const& upload_queue() const; | |
| | | | |
| | | // estimate of how long it will take until we have | |
| | | // received all piece requests that we have sent | |
| | | // if extra_bytes is specified, it will include those | |
| | | // bytes as if they've been requested | |
| | | time_duration download_queue_time(int extra_bytes = 0) const | |
| | | ; | |
| | | | |
| bool is_interesting() const { return m_interesting; } | | bool is_interesting() const { return m_interesting; } | |
| bool is_choked() const { return m_choked; } | | bool is_choked() const { return m_choked; } | |
| | | | |
| bool is_peer_interested() const { return m_peer_interested;
} | | bool is_peer_interested() const { return m_peer_interested;
} | |
| bool has_peer_choked() const { return m_peer_choked; } | | bool has_peer_choked() const { return m_peer_choked; } | |
| | | | |
| void update_interest(); | | void update_interest(); | |
| | | | |
| virtual void get_peer_info(peer_info& p) const; | | virtual void get_peer_info(peer_info& p) const; | |
| | | | |
| skipping to change at line 267 | | skipping to change at line 303 | |
| // returns the torrent this connection is a part of | | // returns the torrent this connection is a part of | |
| // may be zero if the connection is an incoming connection | | // may be zero if the connection is an incoming connection | |
| // and it hasn't received enough information to determine | | // and it hasn't received enough information to determine | |
| // which torrent it should be associated with | | // which torrent it should be associated with | |
| boost::weak_ptr<torrent> associated_torrent() const | | boost::weak_ptr<torrent> associated_torrent() const | |
| { return m_torrent; } | | { return m_torrent; } | |
| | | | |
| const stat& statistics() const { return m_statistics; } | | const stat& statistics() const { return m_statistics; } | |
| void add_stat(size_type downloaded, size_type uploaded); | | void add_stat(size_type downloaded, size_type uploaded); | |
| | | | |
|
| void calc_ip_overhead(); | | | |
| | | | |
| // is called once every second by the main loop | | // is called once every second by the main loop | |
|
| void second_tick(float tick_interval); | | void second_tick(int tick_interval_ms); | |
| | | | |
| void timeout_requests(); | | void timeout_requests(); | |
| | | | |
| boost::shared_ptr<socket_type> get_socket() const { return m
_socket; } | | boost::shared_ptr<socket_type> get_socket() const { return m
_socket; } | |
| tcp::endpoint const& remote() const { return m_remote; } | | tcp::endpoint const& remote() const { return m_remote; } | |
| | | | |
| bitfield const& get_bitfield() const; | | bitfield const& get_bitfield() const; | |
| std::vector<int> const& allowed_fast(); | | std::vector<int> const& allowed_fast(); | |
| std::vector<int> const& suggested_pieces() const { return m_
suggested_pieces; } | | std::vector<int> const& suggested_pieces() const { return m_
suggested_pieces; } | |
| | | | |
| ptime connected_time() const { return m_connect; } | | ptime connected_time() const { return m_connect; } | |
| ptime last_received() const { return m_last_receive; } | | ptime last_received() const { return m_last_receive; } | |
| | | | |
|
| void timed_out(); | | void on_timeout(); | |
| // this will cause this peer_connection to be disconnected. | | // this will cause this peer_connection to be disconnected. | |
|
| void disconnect(char const* message, int error = 0); | | void disconnect(error_code const& ec, int error = 0); | |
| bool is_disconnecting() const { return m_disconnecting; } | | bool is_disconnecting() const { return m_disconnecting; } | |
| | | | |
| // this is called when the connection attempt has succeeded | | // this is called when the connection attempt has succeeded | |
| // and the peer_connection is supposed to set m_connecting | | // and the peer_connection is supposed to set m_connecting | |
| // to false, and stop monitor writability | | // to false, and stop monitor writability | |
| void on_connection_complete(error_code const& e); | | void on_connection_complete(error_code const& e); | |
| | | | |
| // returns true if this connection is still waiting to | | // returns true if this connection is still waiting to | |
| // finish the connection attempt | | // finish the connection attempt | |
| bool is_connecting() const { return m_connecting; } | | bool is_connecting() const { return m_connecting; } | |
| | | | |
| // returns true if the socket of this peer hasn't been | | // returns true if the socket of this peer hasn't been | |
| // attempted to connect yet (i.e. it's queued for | | // attempted to connect yet (i.e. it's queued for | |
| // connection attempt). | | // connection attempt). | |
| bool is_queued() const { return m_queued; } | | bool is_queued() const { return m_queued; } | |
| | | | |
| // called when it's time for this peer_conncetion to actuall
y | | // called when it's time for this peer_conncetion to actuall
y | |
| // initiate the tcp connection. This may be postponed until | | // initiate the tcp connection. This may be postponed until | |
| // the library isn't using up the limitation of half-open | | // the library isn't using up the limitation of half-open | |
| // tcp connections. | | // tcp connections. | |
|
| void connect(int ticket); | | void on_connect(int ticket); | |
| | | | |
| // This is called for every peer right after the upload | | // This is called for every peer right after the upload | |
| // bandwidth has been distributed among them | | // bandwidth has been distributed among them | |
| // It will reset the used bandwidth to 0. | | // It will reset the used bandwidth to 0. | |
| void reset_upload_quota(); | | void reset_upload_quota(); | |
| | | | |
| // free upload. | | // free upload. | |
| size_type total_free_upload() const; | | size_type total_free_upload() const; | |
| void add_free_upload(size_type free_upload); | | void add_free_upload(size_type free_upload); | |
| | | | |
| | | | |
| skipping to change at line 331 | | skipping to change at line 365 | |
| | | | |
| size_type share_diff() const; | | size_type share_diff() const; | |
| | | | |
| // a connection is local if it was initiated by us. | | // a connection is local if it was initiated by us. | |
| // if it was an incoming connection, it is remote | | // if it was an incoming connection, it is remote | |
| bool is_local() const { return m_active; } | | bool is_local() const { return m_active; } | |
| | | | |
| bool on_local_network() const; | | bool on_local_network() const; | |
| bool ignore_bandwidth_limits() const | | bool ignore_bandwidth_limits() const | |
| { return m_ignore_bandwidth_limits; } | | { return m_ignore_bandwidth_limits; } | |
|
| | | void ignore_bandwidth_limits(bool i) | |
| | | { m_ignore_bandwidth_limits = i; } | |
| | | | |
| | | bool ignore_unchoke_slots() const; | |
| | | void ignore_unchoke_slots(bool i) | |
| | | { m_ignore_unchoke_slots = i; } | |
| | | | |
| bool failed() const { return m_failed; } | | bool failed() const { return m_failed; } | |
| | | | |
| int desired_queue_size() const { return m_desired_queue_size
; } | | int desired_queue_size() const { return m_desired_queue_size
; } | |
| | | | |
| // compares this connection against the given connection | | // compares this connection against the given connection | |
| // for which one is more eligible for an unchoke. | | // for which one is more eligible for an unchoke. | |
| // returns true if this is more eligible | | // returns true if this is more eligible | |
| bool unchoke_compare(boost::intrusive_ptr<peer_connection co
nst> const& p) const; | | bool unchoke_compare(boost::intrusive_ptr<peer_connection co
nst> const& p) const; | |
|
| | | bool upload_rate_compare(peer_connection const* p) const; | |
| | | | |
| // resets the byte counters that are used to measure | | // resets the byte counters that are used to measure | |
| // the number of bytes transferred within unchoke cycles | | // the number of bytes transferred within unchoke cycles | |
| void reset_choke_counters(); | | void reset_choke_counters(); | |
| | | | |
| // if this peer connection is useless (neither party is | | // if this peer connection is useless (neither party is | |
| // interested in the other), disconnect it | | // interested in the other), disconnect it | |
| void disconnect_if_redundant(); | | void disconnect_if_redundant(); | |
| | | | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING | |
| | | | |
| skipping to change at line 371 | | skipping to change at line 412 | |
| void incoming_keepalive(); | | void incoming_keepalive(); | |
| void incoming_choke(); | | void incoming_choke(); | |
| void incoming_unchoke(); | | void incoming_unchoke(); | |
| void incoming_interested(); | | void incoming_interested(); | |
| void incoming_not_interested(); | | void incoming_not_interested(); | |
| void incoming_have(int piece_index); | | void incoming_have(int piece_index); | |
| void incoming_bitfield(bitfield const& bits); | | void incoming_bitfield(bitfield const& bits); | |
| void incoming_request(peer_request const& r); | | void incoming_request(peer_request const& r); | |
| void incoming_piece(peer_request const& p, disk_buffer_holde
r& data); | | void incoming_piece(peer_request const& p, disk_buffer_holde
r& data); | |
| void incoming_piece(peer_request const& p, char const* data)
; | | void incoming_piece(peer_request const& p, char const* data)
; | |
|
| void incoming_piece_fragment(); | | void incoming_piece_fragment(int bytes); | |
| | | void start_receive_piece(peer_request const& r); | |
| void incoming_cancel(peer_request const& r); | | void incoming_cancel(peer_request const& r); | |
| | | | |
| void incoming_dht_port(int listen_port); | | void incoming_dht_port(int listen_port); | |
| | | | |
| void incoming_reject_request(peer_request const& r); | | void incoming_reject_request(peer_request const& r); | |
| void incoming_have_all(); | | void incoming_have_all(); | |
| void incoming_have_none(); | | void incoming_have_none(); | |
| void incoming_allowed_fast(int index); | | void incoming_allowed_fast(int index); | |
| void incoming_suggest(int index); | | void incoming_suggest(int index); | |
| | | | |
| // the following functions appends messages | | // the following functions appends messages | |
| // to the send buffer | | // to the send buffer | |
|
| void send_choke(); | | bool send_choke(); | |
| bool send_unchoke(); | | bool send_unchoke(); | |
| void send_interested(); | | void send_interested(); | |
| void send_not_interested(); | | void send_not_interested(); | |
| | | | |
| void snub_peer(); | | void snub_peer(); | |
| | | | |
|
| | | bool can_request_time_critical() const; | |
| | | | |
| | | void make_time_critical(piece_block const& block); | |
| | | | |
| // adds a block to the request queue | | // adds a block to the request queue | |
|
| void add_request(piece_block const& b); | | // returns true if successful, false otherwise | |
| | | enum flags_t { req_time_critical = 1, req_busy = 2 }; | |
| | | bool add_request(piece_block const& b, int flags = 0); | |
| | | | |
| | | // clears the request queue and sends cancels for all messag | |
| | | es | |
| | | // in the download queue | |
| | | void cancel_all_requests(); | |
| | | | |
| // removes a block from the request queue or download queue | | // removes a block from the request queue or download queue | |
| // sends a cancel message if appropriate | | // sends a cancel message if appropriate | |
| // refills the request queue, and possibly ignoring pieces r
equested | | // refills the request queue, and possibly ignoring pieces r
equested | |
| // by peers in the ignore list (to avoid recursion) | | // by peers in the ignore list (to avoid recursion) | |
| void cancel_request(piece_block const& b); | | void cancel_request(piece_block const& b); | |
| void send_block_requests(); | | void send_block_requests(); | |
| | | | |
|
| int max_assignable_bandwidth(int channel) const | | | |
| { return m_bandwidth_limit[channel].max_assignable(); } | | | |
| | | | |
| int bandwidth_throttle(int channel) const | | int bandwidth_throttle(int channel) const | |
|
| { return m_bandwidth_limit[channel].throttle(); } | | { return m_bandwidth_channel[channel].throttle(); } | |
| | | | |
| void assign_bandwidth(int channel, int amount); | | void assign_bandwidth(int channel, int amount); | |
|
| void expire_bandwidth(int channel, int amount); | | | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| ptime m_last_choke; | | ptime m_last_choke; | |
| #endif | | #endif | |
| | | | |
| // is true until we can be sure that the other end | | // is true until we can be sure that the other end | |
| // speaks our protocol (be it bittorrent or http). | | // speaks our protocol (be it bittorrent or http). | |
| virtual bool in_handshake() const = 0; | | virtual bool in_handshake() const = 0; | |
| | | | |
| | | | |
| skipping to change at line 442 | | skipping to change at line 491 | |
| // these functions are virtual to let bt_peer_connection hoo
k into them | | // these functions are virtual to let bt_peer_connection hoo
k into them | |
| // and encrypt the content | | // and encrypt the content | |
| enum message_type_flags { message_type_request = 1 }; | | enum message_type_flags { message_type_request = 1 }; | |
| virtual void send_buffer(char const* begin, int size, int fl
ags = 0); | | virtual void send_buffer(char const* begin, int size, int fl
ags = 0); | |
| virtual buffer::interval allocate_send_buffer(int size); | | virtual buffer::interval allocate_send_buffer(int size); | |
| virtual void setup_send(); | | virtual void setup_send(); | |
| | | | |
| template <class Destructor> | | template <class Destructor> | |
| void append_send_buffer(char* buffer, int size, Destructor c
onst& destructor) | | void append_send_buffer(char* buffer, int size, Destructor c
onst& destructor) | |
| { | | { | |
|
| | | #if TORRENT_DISK_STATS | |
| | | if (m_ses.m_disk_thread.is_disk_buffer(buffer)) | |
| | | m_ses.m_disk_thread.rename_buffer(buffer, "q | |
| | | ueued send buffer"); | |
| | | #endif | |
| m_send_buffer.append_buffer(buffer, size, size, dest
ructor); | | m_send_buffer.append_buffer(buffer, size, size, dest
ructor); | |
|
| #ifdef TORRENT_STATS | | #if defined TORRENT_STATS && defined TORRENT_DISK_STATS | |
| m_ses.m_buffer_usage_logger << log_time() << " appen
d_send_buffer: " << size << std::endl; | | m_ses.m_buffer_usage_logger << log_time() << " appen
d_send_buffer: " << size << std::endl; | |
| m_ses.log_buffer_usage(); | | m_ses.log_buffer_usage(); | |
| #endif | | #endif | |
| } | | } | |
| | | | |
|
| virtual void append_const_send_buffer(char const* buffer, in | | | |
| t size); | | | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| void set_country(char const* c) | | void set_country(char const* c) | |
| { | | { | |
| TORRENT_ASSERT(strlen(c) == 2); | | TORRENT_ASSERT(strlen(c) == 2); | |
| m_country[0] = c[0]; | | m_country[0] = c[0]; | |
| m_country[1] = c[1]; | | m_country[1] = c[1]; | |
| } | | } | |
| bool has_country() const { return m_country[0] != 0; } | | bool has_country() const { return m_country[0] != 0; } | |
| #endif | | #endif | |
| | | | |
| | | | |
| skipping to change at line 480 | | skipping to change at line 531 | |
| { return m_packet_size <= m_recv_pos; } | | { return m_packet_size <= m_recv_pos; } | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| bool piece_failed; | | bool piece_failed; | |
| #endif | | #endif | |
| | | | |
| // upload and download channel state | | // upload and download channel state | |
| // enum from peer_info::bw_state | | // enum from peer_info::bw_state | |
| char m_channel_state[2]; | | char m_channel_state[2]; | |
| | | | |
|
| | | size_type uploaded_since_unchoke() const | |
| | | { return m_statistics.total_payload_upload() - m_uploaded_at | |
| | | _last_unchoke; } | |
| | | | |
| | | size_type downloaded_since_unchoke() const | |
| | | { return m_statistics.total_payload_download() - m_downloade | |
| | | d_at_last_unchoke; } | |
| | | | |
| | | void setup_receive(); | |
| | | | |
| protected: | | protected: | |
| | | | |
| virtual void get_specific_peer_info(peer_info& p) const = 0; | | virtual void get_specific_peer_info(peer_info& p) const = 0; | |
| | | | |
| virtual void write_choke() = 0; | | virtual void write_choke() = 0; | |
| virtual void write_unchoke() = 0; | | virtual void write_unchoke() = 0; | |
| virtual void write_interested() = 0; | | virtual void write_interested() = 0; | |
| virtual void write_not_interested() = 0; | | virtual void write_not_interested() = 0; | |
| virtual void write_request(peer_request const& r) = 0; | | virtual void write_request(peer_request const& r) = 0; | |
| virtual void write_cancel(peer_request const& r) = 0; | | virtual void write_cancel(peer_request const& r) = 0; | |
| | | | |
| skipping to change at line 530 | | skipping to change at line 589 | |
| if (m_recv_buffer.empty()) return buffer::const_inte
rval(0,0); | | if (m_recv_buffer.empty()) return buffer::const_inte
rval(0,0); | |
| return buffer::const_interval(&m_recv_buffer[0] | | return buffer::const_interval(&m_recv_buffer[0] | |
| , &m_recv_buffer[0] + m_recv_pos); | | , &m_recv_buffer[0] + m_recv_pos); | |
| } | | } | |
| | | | |
| bool allocate_disk_receive_buffer(int disk_buffer_size); | | bool allocate_disk_receive_buffer(int disk_buffer_size); | |
| char* release_disk_receive_buffer(); | | char* release_disk_receive_buffer(); | |
| bool has_disk_receive_buffer() const { return m_disk_recv_bu
ffer; } | | bool has_disk_receive_buffer() const { return m_disk_recv_bu
ffer; } | |
| void cut_receive_buffer(int size, int packet_size); | | void cut_receive_buffer(int size, int packet_size); | |
| void reset_recv_buffer(int packet_size); | | void reset_recv_buffer(int packet_size); | |
|
| | | void set_soft_packet_size(int size) { m_soft_packet_size = s | |
| void setup_receive(); | | ize; } | |
| | | | |
| void attach_to_torrent(sha1_hash const& ih); | | void attach_to_torrent(sha1_hash const& ih); | |
| | | | |
| bool verify_piece(peer_request const& p) const; | | bool verify_piece(peer_request const& p) const; | |
| | | | |
| // the bandwidth channels, upload and download | | // the bandwidth channels, upload and download | |
| // keeps track of the current quotas | | // keeps track of the current quotas | |
|
| bandwidth_limit m_bandwidth_limit[num_channels]; | | bandwidth_channel m_bandwidth_channel[num_channels]; | |
| | | | |
| | | // number of bytes this peer can send and receive | |
| | | int m_quota[2]; | |
| | | | |
| // statistics about upload and download speeds | | // statistics about upload and download speeds | |
| // and total amount of uploads and downloads for | | // and total amount of uploads and downloads for | |
| // this peer | | // this peer | |
| stat m_statistics; | | stat m_statistics; | |
| | | | |
| // a back reference to the session | | // a back reference to the session | |
| // the peer belongs to. | | // the peer belongs to. | |
| aux::session_impl& m_ses; | | aux::session_impl& m_ses; | |
| | | | |
| | | | |
| skipping to change at line 594 | | skipping to change at line 655 | |
| return intrusive_ptr_base<peer_connection>::self(); | | return intrusive_ptr_base<peer_connection>::self(); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| private: | | private: | |
| | | | |
| void fill_send_buffer(); | | void fill_send_buffer(); | |
| void on_disk_read_complete(int ret, disk_io_job const& j, pe
er_request r); | | void on_disk_read_complete(int ret, disk_io_job const& j, pe
er_request r); | |
| void on_disk_write_complete(int ret, disk_io_job const& j | | void on_disk_write_complete(int ret, disk_io_job const& j | |
| , peer_request r, boost::shared_ptr<torrent> t); | | , peer_request r, boost::shared_ptr<torrent> t); | |
|
| | | void request_upload_bandwidth( | |
| | | bandwidth_channel* bwc1 | |
| | | , bandwidth_channel* bwc2 = 0 | |
| | | , bandwidth_channel* bwc3 = 0 | |
| | | , bandwidth_channel* bwc4 = 0); | |
| | | void request_download_bandwidth( | |
| | | bandwidth_channel* bwc1 | |
| | | , bandwidth_channel* bwc2 = 0 | |
| | | , bandwidth_channel* bwc3 = 0 | |
| | | , bandwidth_channel* bwc4 = 0); | |
| | | | |
| // keep the io_service running as long as we | | // keep the io_service running as long as we | |
| // have peer connections | | // have peer connections | |
| io_service::work m_work; | | io_service::work m_work; | |
| | | | |
| // the time when we last got a part of a | | // the time when we last got a part of a | |
| // piece packet from this peer | | // piece packet from this peer | |
| ptime m_last_piece; | | ptime m_last_piece; | |
| // the time we sent a request to | | // the time we sent a request to | |
| // this peer the last time | | // this peer the last time | |
| | | | |
| skipping to change at line 656 | | skipping to change at line 727 | |
| // we get free download, and positive on peers | | // we get free download, and positive on peers | |
| // that we give the free upload, to keep the balance. | | // that we give the free upload, to keep the balance. | |
| size_type m_free_upload; | | size_type m_free_upload; | |
| | | | |
| // the total payload download bytes | | // the total payload download bytes | |
| // at the last unchoke cycle. This is used to | | // at the last unchoke cycle. This is used to | |
| // measure the number of bytes transferred during | | // measure the number of bytes transferred during | |
| // an unchoke cycle, to unchoke peers the more bytes | | // an unchoke cycle, to unchoke peers the more bytes | |
| // they sent us | | // they sent us | |
| size_type m_downloaded_at_last_unchoke; | | size_type m_downloaded_at_last_unchoke; | |
|
| | | size_type m_uploaded_at_last_unchoke; | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| std::string m_inet_as_name; | | std::string m_inet_as_name; | |
| #endif | | #endif | |
| | | | |
| buffer m_recv_buffer; | | buffer m_recv_buffer; | |
| | | | |
| // if this peer is receiving a piece, this | | // if this peer is receiving a piece, this | |
| // points to a disk buffer that the data is | | // points to a disk buffer that the data is | |
| // read into. This eliminates a memcopy from | | // read into. This eliminates a memcopy from | |
| | | | |
| skipping to change at line 679 | | skipping to change at line 751 | |
| chained_buffer m_send_buffer; | | chained_buffer m_send_buffer; | |
| | | | |
| boost::shared_ptr<socket_type> m_socket; | | boost::shared_ptr<socket_type> m_socket; | |
| // this is the peer we're actually talking to | | // this is the peer we're actually talking to | |
| // it may not necessarily be the peer we're | | // it may not necessarily be the peer we're | |
| // connected to, in case we use a proxy | | // connected to, in case we use a proxy | |
| tcp::endpoint m_remote; | | tcp::endpoint m_remote; | |
| | | | |
| // this is the torrent this connection is | | // this is the torrent this connection is | |
| // associated with. If the connection is an | | // associated with. If the connection is an | |
|
| // incoming conncetion, this is set to zero | | // incoming connection, this is set to zero | |
| // until the info_hash is received. Then it's | | // until the info_hash is received. Then it's | |
| // set to the torrent it belongs to. | | // set to the torrent it belongs to. | |
| boost::weak_ptr<torrent> m_torrent; | | boost::weak_ptr<torrent> m_torrent; | |
| | | | |
| // remote peer's id | | // remote peer's id | |
| peer_id m_peer_id; | | peer_id m_peer_id; | |
| | | | |
| // the pieces the other end have | | // the pieces the other end have | |
| bitfield m_have_piece; | | bitfield m_have_piece; | |
| | | | |
| // the queue of requests we have got | | // the queue of requests we have got | |
| // from this peer | | // from this peer | |
|
| std::deque<peer_request> m_requests; | | std::vector<peer_request> m_requests; | |
| | | | |
| // the blocks we have reserved in the piece | | // the blocks we have reserved in the piece | |
| // picker and will request from this peer. | | // picker and will request from this peer. | |
|
| std::deque<piece_block> m_request_queue; | | std::vector<pending_block> m_request_queue; | |
| | | | |
| // the queue of blocks we have requested | | // the queue of blocks we have requested | |
| // from this peer | | // from this peer | |
|
| std::deque<pending_block> m_download_queue; | | std::vector<pending_block> m_download_queue; | |
| | | | |
| // the pieces we will send to the peer | | // the pieces we will send to the peer | |
| // if requested (regardless of choke state) | | // if requested (regardless of choke state) | |
|
| std::set<int> m_accept_fast; | | std::vector<int> m_accept_fast; | |
| | | | |
| // the pieces the peer will send us if | | // the pieces the peer will send us if | |
| // requested (regardless of choke state) | | // requested (regardless of choke state) | |
| std::vector<int> m_allowed_fast; | | std::vector<int> m_allowed_fast; | |
| | | | |
| // pieces that has been suggested to be | | // pieces that has been suggested to be | |
| // downloaded from this peer | | // downloaded from this peer | |
| std::vector<int> m_suggested_pieces; | | std::vector<int> m_suggested_pieces; | |
| | | | |
| // a list of byte offsets inside the send buffer | | // a list of byte offsets inside the send buffer | |
| // the piece requests | | // the piece requests | |
| std::vector<int> m_requests_in_buffer; | | std::vector<int> m_requests_in_buffer; | |
| | | | |
|
| | | // the block we're currently receiving. Or | |
| | | // (-1, -1) if we're not receiving one | |
| | | piece_block m_receiving_block; | |
| | | | |
| | | // the number of bytes that the other | |
| | | // end has to send us in order to respond | |
| | | // to all outstanding piece requests we | |
| | | // have sent to it | |
| | | int m_outstanding_bytes; | |
| | | | |
| | | // the number of outstanding bytes expected | |
| | | // to be received by extensions | |
| | | int m_extension_outstanding_bytes; | |
| | | | |
| | | // the number of time critical requests | |
| | | // queued up in the m_request_queue that | |
| | | // soon will be committed to the download | |
| | | // queue. This is included in download_queue_time() | |
| | | // so that it can be used while adding more | |
| | | // requests and take the previous requests | |
| | | // into account without submitting it all | |
| | | // immediately | |
| | | int m_queued_time_critical; | |
| | | | |
| // the number of pieces this peer | | // the number of pieces this peer | |
| // has. Must be the same as | | // has. Must be the same as | |
| // std::count(m_have_piece.begin(), | | // std::count(m_have_piece.begin(), | |
| // m_have_piece.end(), true) | | // m_have_piece.end(), true) | |
| int m_num_pieces; | | int m_num_pieces; | |
| | | | |
| // the timeout in seconds | | // the timeout in seconds | |
| int m_timeout; | | int m_timeout; | |
| | | | |
| // the size (in bytes) of the bittorrent message | | // the size (in bytes) of the bittorrent message | |
| // we're currently receiving | | // we're currently receiving | |
| int m_packet_size; | | int m_packet_size; | |
| | | | |
|
| | | // some messages needs to be read from the socket | |
| | | // buffer in multiple stages. This soft packet | |
| | | // size limits the read size between message handler | |
| | | // dispatch. Ignored when set to 0 | |
| | | int m_soft_packet_size; | |
| | | | |
| // the number of bytes of the bittorrent payload | | // the number of bytes of the bittorrent payload | |
| // we've received so far | | // we've received so far | |
| int m_recv_pos; | | int m_recv_pos; | |
| | | | |
| int m_disk_recv_buffer_size; | | int m_disk_recv_buffer_size; | |
| | | | |
| // the number of bytes we are currently reading | | // the number of bytes we are currently reading | |
| // from disk, that will be added to the send | | // from disk, that will be added to the send | |
| // buffer as soon as they complete | | // buffer as soon as they complete | |
| int m_reading_bytes; | | int m_reading_bytes; | |
| | | | |
| skipping to change at line 774 | | skipping to change at line 876 | |
| // it allows some variance without changing | | // it allows some variance without changing | |
| // back and forth between states | | // back and forth between states | |
| peer_speed_t m_speed; | | peer_speed_t m_speed; | |
| | | | |
| // the ticket id from the connection queue. | | // the ticket id from the connection queue. | |
| // This is used to identify the connection | | // This is used to identify the connection | |
| // so that it can be removed from the queue | | // so that it can be removed from the queue | |
| // once the connection completes | | // once the connection completes | |
| int m_connection_ticket; | | int m_connection_ticket; | |
| | | | |
|
| | | // if this is -1, superseeding is not active. If it is >= 0 | |
| | | // this is the piece that is available to this peer. Only | |
| | | // this piece can be downloaded from us by this peer. | |
| | | // This will remain the current piece for this peer until | |
| | | // another peer sends us a have message for this piece | |
| | | int m_superseed_piece; | |
| | | | |
| // bytes downloaded since last second | | // bytes downloaded since last second | |
| // timer timeout; used for determining | | // timer timeout; used for determining | |
| // approx download rate | | // approx download rate | |
| int m_remote_bytes_dled; | | int m_remote_bytes_dled; | |
| | | | |
| // approximate peer download rate | | // approximate peer download rate | |
| int m_remote_dl_rate; | | int m_remote_dl_rate; | |
| | | | |
| // the number of bytes send to the disk-io | | // the number of bytes send to the disk-io | |
| // thread that hasn't yet been completely written. | | // thread that hasn't yet been completely written. | |
| | | | |
| skipping to change at line 808 | | skipping to change at line 917 | |
| // where n is the value of this variable. | | // where n is the value of this variable. | |
| // if it is 0, the download rate limit setting | | // if it is 0, the download rate limit setting | |
| // will be used to determine if whole pieces | | // will be used to determine if whole pieces | |
| // are preferred. | | // are preferred. | |
| boost::uint8_t m_prefer_whole_pieces; | | boost::uint8_t m_prefer_whole_pieces; | |
| | | | |
| // the number of request we should queue up | | // the number of request we should queue up | |
| // at the remote end. | | // at the remote end. | |
| boost::uint8_t m_desired_queue_size; | | boost::uint8_t m_desired_queue_size; | |
| | | | |
|
| | | // the number of piece requests we have rejected | |
| | | // in a row because the peer is choked. This is | |
| | | // used to re-send the choked message in case the | |
| | | // other end keeps requesting pieces while being | |
| | | // choked, and eventuelly disconnect if it keeps | |
| | | // requesting too many pieces while being choked | |
| | | boost::uint8_t m_choke_rejects; | |
| | | | |
| // if this is true, the disconnection | | // if this is true, the disconnection | |
| // timestamp is not updated when the connection | | // timestamp is not updated when the connection | |
| // is closed. This means the time until we can | | // is closed. This means the time until we can | |
| // reconnect to this peer is shorter, and likely | | // reconnect to this peer is shorter, and likely | |
| // immediate. | | // immediate. | |
| bool m_fast_reconnect:1; | | bool m_fast_reconnect:1; | |
| | | | |
| // is true if it was we that connected to the peer | | // is true if it was we that connected to the peer | |
| // and false if we got an incoming connection | | // and false if we got an incoming connection | |
| // could be considered: true = local, false = remote | | // could be considered: true = local, false = remote | |
| | | | |
| skipping to change at line 845 | | skipping to change at line 962 | |
| // out or closed the connection. In that | | // out or closed the connection. In that | |
| // case we will not try to reconnect to | | // case we will not try to reconnect to | |
| // this peer | | // this peer | |
| bool m_failed:1; | | bool m_failed:1; | |
| | | | |
| // if this is set to true, the peer will not | | // if this is set to true, the peer will not | |
| // request bandwidth from the limiter, but instead | | // request bandwidth from the limiter, but instead | |
| // just send and receive as much as possible. | | // just send and receive as much as possible. | |
| bool m_ignore_bandwidth_limits:1; | | bool m_ignore_bandwidth_limits:1; | |
| | | | |
|
| | | // set to true if this peer controls its unchoke | |
| | | // state individually, regardless of the global | |
| | | // unchoker | |
| | | bool m_ignore_unchoke_slots:1; | |
| | | | |
| // this is set to true when a have_all | | // this is set to true when a have_all | |
| // message is received. This information | | // message is received. This information | |
| // is used to fill the bitmask in init() | | // is used to fill the bitmask in init() | |
| bool m_have_all:1; | | bool m_have_all:1; | |
| | | | |
| // this is true if this connection has been added | | // this is true if this connection has been added | |
| // to the list of connections that will be closed. | | // to the list of connections that will be closed. | |
| bool m_disconnecting:1; | | bool m_disconnecting:1; | |
| | | | |
| // this is true until this socket has become | | // this is true until this socket has become | |
| | | | |
| skipping to change at line 888 | | skipping to change at line 1010 | |
| bool m_upload_only:1; | | bool m_upload_only:1; | |
| | | | |
| // set to true when a piece request times out. The | | // set to true when a piece request times out. The | |
| // result is that the desired pending queue size | | // result is that the desired pending queue size | |
| // is set to 1 | | // is set to 1 | |
| bool m_snubbed:1; | | bool m_snubbed:1; | |
| | | | |
| // this is set to true once the bitfield is received | | // this is set to true once the bitfield is received | |
| bool m_bitfield_received:1; | | bool m_bitfield_received:1; | |
| | | | |
|
| | | // if this is set to true, the client will not | |
| | | // pick any pieces from this peer | |
| | | bool m_no_download:1; | |
| | | | |
| | | template <std::size_t Size> | |
| | | struct handler_storage | |
| | | { | |
| | | #ifdef TORRENT_DEBUG | |
| | | handler_storage() | |
| | | : used(false) | |
| | | {} | |
| | | | |
| | | bool used; | |
| | | #endif | |
| | | boost::aligned_storage<Size> bytes; | |
| | | }; | |
| | | | |
| | | handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_read_handle | |
| | | r_storage; | |
| | | handler_storage<TORRENT_WRITE_HANDLER_MAX_SIZE> m_write_hand | |
| | | ler_storage; | |
| | | | |
| | | template <class Handler, std::size_t Size> | |
| | | struct allocating_handler | |
| | | { | |
| | | allocating_handler( | |
| | | Handler const& h, handler_storage<Size>& s | |
| | | ) | |
| | | : handler(h) | |
| | | , storage(s) | |
| | | {} | |
| | | | |
| | | template <class A0> | |
| | | void operator()(A0 const& a0) const | |
| | | { | |
| | | handler(a0); | |
| | | } | |
| | | | |
| | | template <class A0, class A1> | |
| | | void operator()(A0 const& a0, A1 const& a1) const | |
| | | { | |
| | | handler(a0, a1); | |
| | | } | |
| | | | |
| | | template <class A0, class A1, class A2> | |
| | | void operator()(A0 const& a0, A1 const& a1, A2 const | |
| | | & a2) const | |
| | | { | |
| | | handler(a0, a1, a2); | |
| | | } | |
| | | | |
| | | friend void* asio_handler_allocate( | |
| | | std::size_t size, allocating_handler<Handler, Si | |
| | | ze>* ctx) | |
| | | { | |
| | | assert(size <= Size); | |
| | | #ifdef TORRENT_DEBUG | |
| | | assert(!ctx->storage.used); | |
| | | ctx->storage.used = true; | |
| | | #endif | |
| | | return &ctx->storage.bytes; | |
| | | } | |
| | | | |
| | | friend void asio_handler_deallocate( | |
| | | void*, std::size_t, allocating_handler<Handl | |
| | | er, Size>* ctx) | |
| | | { | |
| | | #ifdef TORRENT_DEBUG | |
| | | ctx->storage.used = false; | |
| | | #endif | |
| | | } | |
| | | | |
| | | Handler handler; | |
| | | handler_storage<Size>& storage; | |
| | | }; | |
| | | | |
| | | template <class Handler> | |
| | | allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE> | |
| | | make_read_handler(Handler const& handler) | |
| | | { | |
| | | return allocating_handler<Handler, TORRENT_READ_HAND | |
| | | LER_MAX_SIZE>( | |
| | | handler, m_read_handler_storage | |
| | | ); | |
| | | } | |
| | | | |
| | | template <class Handler> | |
| | | allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE> | |
| | | make_write_handler(Handler const& handler) | |
| | | { | |
| | | return allocating_handler<Handler, TORRENT_WRITE_HAN | |
| | | DLER_MAX_SIZE>( | |
| | | handler, m_write_handler_storage | |
| | | ); | |
| | | } | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| public: | | public: | |
| bool m_in_constructor:1; | | bool m_in_constructor:1; | |
| bool m_disconnect_started:1; | | bool m_disconnect_started:1; | |
| bool m_initialized:1; | | bool m_initialized:1; | |
|
| | | int m_received_in_piece; | |
| #endif | | #endif | |
| }; | | }; | |
| } | | } | |
| | | | |
| #endif // TORRENT_PEER_CONNECTION_HPP_INCLUDED | | #endif // TORRENT_PEER_CONNECTION_HPP_INCLUDED | |
| | | | |
End of changes. 46 change blocks. |
| 42 lines changed or deleted | | 267 lines changed or added | |
|
| policy.hpp | | policy.hpp | |
| | | | |
| skipping to change at line 37 | | skipping to change at line 37 | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_POLICY_HPP_INCLUDED | | #ifndef TORRENT_POLICY_HPP_INCLUDED | |
| #define TORRENT_POLICY_HPP_INCLUDED | | #define TORRENT_POLICY_HPP_INCLUDED | |
| | | | |
| #include <algorithm> | | #include <algorithm> | |
|
| #include <vector> | | #include <deque> | |
| | | | |
| #ifdef _MSC_VER | | | |
| #pragma warning(push, 1) | | | |
| #endif | | | |
| | | | |
| #ifdef _MSC_VER | | | |
| #pragma warning(pop) | | | |
| #endif | | | |
| | | | |
| #include "libtorrent/peer.hpp" | | #include "libtorrent/peer.hpp" | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/size_type.hpp" | | #include "libtorrent/size_type.hpp" | |
| #include "libtorrent/invariant_check.hpp" | | #include "libtorrent/invariant_check.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/time.hpp" | | #include "libtorrent/time.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| | | | |
| class torrent; | | class torrent; | |
| class peer_connection; | | class peer_connection; | |
| | | | |
|
| | | // this is compressed as an unsigned floating point value | |
| | | // the top 13 bits are the mantissa and the low | |
| | | // 3 bits is the unsigned exponent. The exponent | |
| | | // has an implicit + 4 as well. | |
| | | // This means that the resolution is no less than 16 | |
| | | // The actual rate is: (upload_rate >> 4) << ((upload_rate & 0xf) + | |
| | | 4) | |
| | | // the resolution gets worse the higher the value is | |
| | | // min value is 0, max value is 16775168 | |
| | | struct ufloat16 | |
| | | { | |
| | | ufloat16() {} | |
| | | ufloat16(int v) | |
| | | { *this = v; } | |
| | | operator int() | |
| | | { | |
| | | return (m_val >> 3) << ((m_val & 7) + 4); | |
| | | } | |
| | | | |
| | | ufloat16& operator=(int v) | |
| | | { | |
| | | if (v > 0x1fff << (7 + 4)) m_val = 0xffff; | |
| | | else if (v <= 0) m_val = 0; | |
| | | else | |
| | | { | |
| | | int exp = 4; | |
| | | v >>= 4; | |
| | | while (v > 0x1fff) | |
| | | { | |
| | | v >>= 1; | |
| | | ++exp; | |
| | | } | |
| | | TORRENT_ASSERT(exp <= 7); | |
| | | m_val = (v << 3) || (exp & 7); | |
| | | } | |
| | | return *this; | |
| | | } | |
| | | private: | |
| | | unsigned int m_val; | |
| | | }; | |
| | | | |
| enum | | enum | |
| { | | { | |
| // the limits of the download queue size | | // the limits of the download queue size | |
| min_request_queue = 2, | | min_request_queue = 2, | |
| | | | |
| // the amount of free upload allowed before | | // the amount of free upload allowed before | |
| // the peer is choked | | // the peer is choked | |
| free_upload_amount = 4 * 16 * 1024 | | free_upload_amount = 4 * 16 * 1024 | |
| }; | | }; | |
| | | | |
| | | | |
| skipping to change at line 86 | | skipping to change at line 118 | |
| | | | |
| policy(torrent* t); | | policy(torrent* t); | |
| | | | |
| // this is called every 10 seconds to allow | | // this is called every 10 seconds to allow | |
| // for peer choking management | | // for peer choking management | |
| void pulse(); | | void pulse(); | |
| | | | |
| struct peer; | | struct peer; | |
| // this is called once for every peer we get from | | // this is called once for every peer we get from | |
| // the tracker, pex, lsd or dht. | | // the tracker, pex, lsd or dht. | |
|
| policy::peer* peer_from_tracker(const tcp::endpoint& remote,
const peer_id& pid | | policy::peer* add_peer(const tcp::endpoint& remote, const pe
er_id& pid | |
| , int source, char flags); | | , int source, char flags); | |
| | | | |
| // false means duplicate connection | | // false means duplicate connection | |
| bool update_peer_port(int port, policy::peer* p, int src); | | bool update_peer_port(int port, policy::peer* p, int src); | |
| | | | |
| // called when an incoming connection is accepted | | // called when an incoming connection is accepted | |
| // false means the connection was refused or failed | | // false means the connection was refused or failed | |
|
| bool new_connection(peer_connection& c); | | bool new_connection(peer_connection& c, int session_time); | |
| | | | |
| // the given connection was just closed | | // the given connection was just closed | |
|
| void connection_closed(const peer_connection& c); | | void connection_closed(const peer_connection& c, int session
_time); | |
| | | | |
| void ban_peer(policy::peer* p); | | void ban_peer(policy::peer* p); | |
|
| | | void set_connection(policy::peer* p, peer_connection* c); | |
| | | void set_failcount(policy::peer* p, int f); | |
| | | | |
| // the peer has got at least one interesting piece | | // the peer has got at least one interesting piece | |
| void peer_is_interesting(peer_connection& c); | | void peer_is_interesting(peer_connection& c); | |
| | | | |
|
| // the peer unchoked us | | | |
| void unchoked(peer_connection& c); | | | |
| | | | |
| // the peer is interested in our pieces | | | |
| void interested(peer_connection& c); | | | |
| | | | |
| // the peer is not interested in our pieces | | | |
| void not_interested(peer_connection& c); | | | |
| | | | |
| void ip_filter_updated(); | | void ip_filter_updated(); | |
| | | | |
| void set_seed(policy::peer* p, bool s); | | void set_seed(policy::peer* p, bool s); | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| bool has_connection(const peer_connection* p); | | bool has_connection(const peer_connection* p); | |
| | | | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
|
| struct peer | | // intended struct layout (on 32 bit architectures) | |
| | | // offset size alignment field | |
| | | // 0 12 1 prev_amount_upload, prev_amount_download | |
| | | // 12 4 4 connection | |
| | | // 16 2 2 last_optimistically_unchoked | |
| | | // 18 2 2 last_connected | |
| | | // 20 16 1 addr | |
| | | // 36 2 2 port | |
| | | // 38 2 2 upload_rate_limit | |
| | | // 40 2 2 download_rate_limit | |
| | | // 42 1 1 hashfails | |
| | | // 43 1 1 failcount, connectable, optimistically_unchoked, | |
| | | seed | |
| | | // 44 1 1 fast_reconnects, trust_points | |
| | | // 45 1 1 source, pe_support, is_v6_addr | |
| | | // 46 1 1 on_parole, banned, added_to_dht | |
| | | // 47 1 1 <padding> | |
| | | // 48 | |
| | | struct TORRENT_EXPORT peer | |
| { | | { | |
|
| enum connection_type { not_connectable, connectable | | peer(); | |
| }; | | peer(boost::uint16_t port, bool connectable, int src | |
| peer(tcp::endpoint const& ip, connection_type t, int | | ); | |
| src); | | | |
| | | | |
| size_type total_download() const; | | size_type total_download() const; | |
| size_type total_upload() const; | | size_type total_upload() const; | |
| | | | |
|
| tcp::endpoint ip() const { return tcp::endpoint(addr | | libtorrent::address address() const; | |
| , port); } | | | |
| void set_ip(tcp::endpoint const& endp) | | tcp::endpoint ip() const { return tcp::endpoint(addr | |
| { addr = endp.address(); port = endp.port(); } | | ess(), port); } | |
| | | | |
| // this is the accumulated amount of | | // this is the accumulated amount of | |
| // uploaded and downloaded data to this | | // uploaded and downloaded data to this | |
| // peer. It only accounts for what was | | // peer. It only accounts for what was | |
| // shared during the last connection to | | // shared during the last connection to | |
| // this peer. i.e. These are only updated | | // this peer. i.e. These are only updated | |
| // when the connection is closed. For the | | // when the connection is closed. For the | |
| // total amount of upload and download | | // total amount of upload and download | |
| // we'll have to add thes figures with the | | // we'll have to add thes figures with the | |
| // statistics from the peer_connection. | | // statistics from the peer_connection. | |
|
| size_type prev_amount_upload; | | // 48 bits can fit 256 Terabytes | |
| size_type prev_amount_download; | | #ifdef __SUNPRO_CC | |
| | | unsigned prev_amount_upload:48; | |
| // the ip address this peer is or was connected on | | unsigned prev_amount_download:48; | |
| address addr; | | #else | |
| | | boost::uint64_t prev_amount_upload:48; | |
| // the time when this peer was optimistically unchok | | boost::uint64_t prev_amount_download:48; | |
| ed | | #endif | |
| // the last time. | | | |
| libtorrent::ptime last_optimistically_unchoked; | | | |
| | | | |
| // the time when the peer connected to us | | | |
| // or disconnected if it isn't connected right now | | | |
| libtorrent::ptime connected; | | | |
| | | | |
| // if the peer is connected now, this | | // if the peer is connected now, this | |
| // will refer to a valid peer_connection | | // will refer to a valid peer_connection | |
| peer_connection* connection; | | peer_connection* connection; | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| // only used in debug mode to assert that | | // only used in debug mode to assert that | |
| // the first entry in the AS pair keeps the same | | // the first entry in the AS pair keeps the same | |
| boost::uint16_t inet_as_num; | | boost::uint16_t inet_as_num; | |
| #endif | | #endif | |
| // The AS this peer belongs to | | // The AS this peer belongs to | |
| std::pair<const int, int>* inet_as; | | std::pair<const int, int>* inet_as; | |
| #endif | | #endif | |
| | | | |
|
| | | // the time when this peer was optimistically unchok | |
| | | ed | |
| | | // the last time. in seconds since session was creat | |
| | | ed | |
| | | // 16 bits is enough to last for 18.2 hours | |
| | | // when the session time reaches 18 hours, it jumps | |
| | | back by | |
| | | // 9 hours, and all peers' times are updated to be | |
| | | // relative to that new time offset | |
| | | boost::uint16_t last_optimistically_unchoked; | |
| | | | |
| | | // the time when the peer connected to us | |
| | | // or disconnected if it isn't connected right now | |
| | | // in number of seconds since session was created | |
| | | boost::uint16_t last_connected; | |
| | | | |
| // the port this peer is or was connected on | | // the port this peer is or was connected on | |
| boost::uint16_t port; | | boost::uint16_t port; | |
| | | | |
|
| | | // the upload and download rate limits set for this | |
| | | peer | |
| | | ufloat16 upload_rate_limit; | |
| | | ufloat16 download_rate_limit; | |
| | | | |
| | | // the number of times this peer has been | |
| | | // part of a piece that failed the hash check | |
| | | boost::uint8_t hashfails; | |
| | | | |
| // the number of failed connection attempts | | // the number of failed connection attempts | |
| // this peer has | | // this peer has | |
|
| boost::uint8_t failcount; | | unsigned failcount:5; // [0, 31] | |
| | | | |
| | | // incoming peers (that don't advertize their listen | |
| | | port) | |
| | | // will not be considered connectable. Peers that | |
| | | // we have a listen port for will be assumed to be. | |
| | | bool connectable:1; | |
| | | | |
| | | // true if this peer currently is unchoked | |
| | | // because of an optimistic unchoke. | |
| | | // when the optimistic unchoke is moved to | |
| | | // another peer, this peer will be choked | |
| | | // if this is true | |
| | | bool optimistically_unchoked:1; | |
| | | | |
| | | // this is true if the peer is a seed | |
| | | bool seed:1; | |
| | | | |
| | | // the number of times we have allowed a fast | |
| | | // reconnect for this peer. | |
| | | unsigned fast_reconnects:4; | |
| | | | |
| // for every valid piece we receive where this | | // for every valid piece we receive where this | |
| // peer was one of the participants, we increase | | // peer was one of the participants, we increase | |
| // this value. For every invalid piece we receive | | // this value. For every invalid piece we receive | |
| // where this peer was a participant, we decrease | | // where this peer was a participant, we decrease | |
| // this value. If it sinks below a threshold, its | | // this value. If it sinks below a threshold, its | |
| // considered a bad peer and will be banned. | | // considered a bad peer and will be banned. | |
|
| boost::int8_t trust_points; | | signed trust_points:4; // [-7, 8] | |
| | | | |
| // a bitmap combining the peer_source flags | | // a bitmap combining the peer_source flags | |
| // from peer_info. | | // from peer_info. | |
|
| boost::uint8_t source; | | unsigned source:6; | |
| | | | |
| // the number of times this peer has been | | | |
| // part of a piece that failed the hash check | | | |
| boost::uint8_t hashfails; | | | |
| | | | |
| // type specifies if the connection was incoming | | | |
| // or outgoing. If we ever saw this peer as connecta | | | |
| ble | | | |
| // it will remain as connectable | | | |
| unsigned type:4; | | | |
| | | | |
| // the number of times we have allowed a fast | | | |
| // reconnect for this peer. | | | |
| unsigned fast_reconnects:4; | | | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| // Hints encryption support of peer. Only effective | | // Hints encryption support of peer. Only effective | |
| // for and when the outgoing encryption policy | | // for and when the outgoing encryption policy | |
| // allows both encrypted and non encrypted | | // allows both encrypted and non encrypted | |
| // connections (pe_settings::out_enc_policy | | // connections (pe_settings::out_enc_policy | |
| // == enabled). The initial state of this flag | | // == enabled). The initial state of this flag | |
| // determines the initial connection attempt | | // determines the initial connection attempt | |
| // type (true = encrypted, false = standard). | | // type (true = encrypted, false = standard). | |
| // This will be toggled everytime either an | | // This will be toggled everytime either an | |
| // encrypted or non-encrypted handshake fails. | | // encrypted or non-encrypted handshake fails. | |
| bool pe_support:1; | | bool pe_support:1; | |
| #endif | | #endif | |
|
| // true if this peer currently is unchoked | | | |
| // because of an optimistic unchoke. | | | |
| // when the optimistic unchoke is moved to | | | |
| // another peer, this peer will be choked | | | |
| // if this is true | | | |
| bool optimistically_unchoked:1; | | | |
| | | | |
|
| // this is true if the peer is a seed | | #if TORRENT_USE_IPV6 | |
| bool seed:1; | | // this is true if the v6 union member in addr is | |
| | | // the one to use, false if it's the v4 one | |
| | | bool is_v6_addr:1; | |
| | | #endif | |
| | | | |
| // if this is true, the peer has previously | | // if this is true, the peer has previously | |
| // participated in a piece that failed the piece | | // participated in a piece that failed the piece | |
| // hash check. This will put the peer on parole | | // hash check. This will put the peer on parole | |
| // and only request entire pieces. If a piece pass | | // and only request entire pieces. If a piece pass | |
| // that was partially requested from this peer it | | // that was partially requested from this peer it | |
| // will leave parole mode and continue download | | // will leave parole mode and continue download | |
| // pieces as normal peers. | | // pieces as normal peers. | |
| bool on_parole:1; | | bool on_parole:1; | |
| | | | |
| // is set to true if this peer has been banned | | // is set to true if this peer has been banned | |
| bool banned:1; | | bool banned:1; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| // this is set to true when this peer as been | | // this is set to true when this peer as been | |
| // pinged by the DHT | | // pinged by the DHT | |
| bool added_to_dht:1; | | bool added_to_dht:1; | |
| #endif | | #endif | |
| }; | | }; | |
| | | | |
|
| | | struct TORRENT_EXPORT ipv4_peer : peer | |
| | | { | |
| | | ipv4_peer(tcp::endpoint const& ip, bool connectable, | |
| | | int src); | |
| | | ipv4_peer(libtorrent::address const& a); | |
| | | | |
| | | address_v4 addr; | |
| | | }; | |
| | | | |
| | | #if TORRENT_USE_IPV6 | |
| | | struct TORRENT_EXPORT ipv6_peer : peer | |
| | | { | |
| | | ipv6_peer(tcp::endpoint const& ip, bool connectable, | |
| | | int src); | |
| | | ipv6_peer(libtorrent::address const& a); | |
| | | | |
| | | address_v6::bytes_type addr; | |
| | | }; | |
| | | #endif | |
| | | | |
| int num_peers() const { return m_peers.size(); } | | int num_peers() const { return m_peers.size(); } | |
| | | | |
|
| typedef std::multimap<address, peer>::iterator iterator; | | struct peer_address_compare | |
| typedef std::multimap<address, peer>::const_iterator const_i | | { | |
| terator; | | bool operator()( | |
| | | peer const* lhs, libtorrent::address const& | |
| | | rhs) const | |
| | | { | |
| | | return lhs->address() < rhs; | |
| | | } | |
| | | | |
| | | bool operator()( | |
| | | libtorrent::address const& lhs, peer const* | |
| | | rhs) const | |
| | | { | |
| | | return lhs < rhs->address(); | |
| | | } | |
| | | | |
| | | bool operator()( | |
| | | peer const* lhs, peer const* rhs) const | |
| | | { | |
| | | return lhs->address() < rhs->address(); | |
| | | } | |
| | | }; | |
| | | | |
| | | typedef std::deque<peer*> peers_t; | |
| | | | |
| | | typedef peers_t::iterator iterator; | |
| | | typedef peers_t::const_iterator const_iterator; | |
| iterator begin_peer() { return m_peers.begin(); } | | iterator begin_peer() { return m_peers.begin(); } | |
| iterator end_peer() { return m_peers.end(); } | | iterator end_peer() { return m_peers.end(); } | |
| const_iterator begin_peer() const { return m_peers.begin();
} | | const_iterator begin_peer() const { return m_peers.begin();
} | |
| const_iterator end_peer() const { return m_peers.end(); } | | const_iterator end_peer() const { return m_peers.end(); } | |
|
| | | | |
| std::pair<iterator, iterator> find_peers(address const& a) | | std::pair<iterator, iterator> find_peers(address const& a) | |
|
| { return m_peers.equal_range(a); } | | { | |
| | | return std::equal_range( | |
| | | m_peers.begin(), m_peers.end(), a, peer_addr | |
| | | ess_compare()); | |
| | | } | |
| | | | |
|
| bool connect_one_peer(); | | std::pair<const_iterator, const_iterator> find_peers(address | |
| | | const& a) const | |
| | | { | |
| | | return std::equal_range( | |
| | | m_peers.begin(), m_peers.end(), a, peer_addr | |
| | | ess_compare()); | |
| | | } | |
| | | | |
| | | bool connect_one_peer(int session_time); | |
| | | | |
| bool has_peer(policy::peer const* p) const; | | bool has_peer(policy::peer const* p) const; | |
| | | | |
| int num_seeds() const { return m_num_seeds; } | | int num_seeds() const { return m_num_seeds; } | |
| int num_connect_candidates() const { return m_num_connect_ca
ndidates; } | | int num_connect_candidates() const { return m_num_connect_ca
ndidates; } | |
| void recalculate_connect_candidates(); | | void recalculate_connect_candidates(); | |
| | | | |
|
| | | void erase_peer(policy::peer* p); | |
| void erase_peer(iterator i); | | void erase_peer(iterator i); | |
| | | | |
| private: | | private: | |
| | | | |
|
| | | bool compare_peer_erase(policy::peer const& lhs, policy::pee
r const& rhs) const; | |
| bool compare_peer(policy::peer const& lhs, policy::peer cons
t& rhs | | bool compare_peer(policy::peer const& lhs, policy::peer cons
t& rhs | |
| , address const& external_ip) const; | | , address const& external_ip) const; | |
| | | | |
|
| iterator find_connect_candidate(); | | iterator find_connect_candidate(int session_time); | |
| | | | |
| bool is_connect_candidate(peer const& p, bool finished) cons
t; | | bool is_connect_candidate(peer const& p, bool finished) cons
t; | |
|
| | | bool is_erase_candidate(peer const& p, bool finished) const; | |
| | | bool should_erase_immediately(peer const& p) const; | |
| | | | |
|
| std::multimap<address, peer> m_peers; | | void erase_peers(); | |
| | | | |
| | | peers_t m_peers; | |
| | | | |
| // since the peer list can grow too large | | // since the peer list can grow too large | |
| // to scan all of it, start at this iterator | | // to scan all of it, start at this iterator | |
|
| iterator m_round_robin; | | int m_round_robin; | |
| | | | |
| torrent* m_torrent; | | torrent* m_torrent; | |
| | | | |
|
| // free download we have got that hasn't | | | |
| // been distributed yet. | | | |
| size_type m_available_free_upload; | | | |
| | | | |
| // The number of peers in our peer list | | // The number of peers in our peer list | |
| // that are connect candidates. i.e. they're | | // that are connect candidates. i.e. they're | |
| // not already connected and they have not | | // not already connected and they have not | |
| // yet reached their max try count and they | | // yet reached their max try count and they | |
| // have the connectable state (we have a listen | | // have the connectable state (we have a listen | |
| // port for them). | | // port for them). | |
| int m_num_connect_candidates; | | int m_num_connect_candidates; | |
| | | | |
| // the number of seeds in the peer list | | // the number of seeds in the peer list | |
| int m_num_seeds; | | int m_num_seeds; | |
| | | | |
| skipping to change at line 309 | | skipping to change at line 423 | |
| // last time we recalculated the number of | | // last time we recalculated the number of | |
| // connect candidates. Since seeds (or upload | | // connect candidates. Since seeds (or upload | |
| // only) peers are not connect candidates | | // only) peers are not connect candidates | |
| // when we're finished, the set depends on | | // when we're finished, the set depends on | |
| // this state. Every time m_torrent->is_finished() | | // this state. Every time m_torrent->is_finished() | |
| // is different from this state, we need to | | // is different from this state, we need to | |
| // recalculate the connect candidates. | | // recalculate the connect candidates. | |
| bool m_finished; | | bool m_finished; | |
| }; | | }; | |
| | | | |
|
| | | inline policy::ipv4_peer::ipv4_peer( | |
| | | tcp::endpoint const& ep, bool c, int src | |
| | | ) | |
| | | : peer(ep.port(), c, src) | |
| | | , addr(ep.address().to_v4()) | |
| | | { | |
| | | is_v6_addr = false; | |
| | | } | |
| | | | |
| | | inline policy::ipv4_peer::ipv4_peer(libtorrent::address const& a) | |
| | | : addr(a.to_v4()) | |
| | | { | |
| | | is_v6_addr = false; | |
| | | } | |
| | | | |
| | | inline policy::ipv6_peer::ipv6_peer( | |
| | | tcp::endpoint const& ep, bool c, int src | |
| | | ) | |
| | | : peer(ep.port(), c, src) | |
| | | , addr(ep.address().to_v6().to_bytes()) | |
| | | { | |
| | | is_v6_addr = true; | |
| | | } | |
| | | | |
| | | inline policy::ipv6_peer::ipv6_peer(libtorrent::address const& a) | |
| | | : addr(a.to_v6().to_bytes()) | |
| | | { | |
| | | is_v6_addr = true; | |
| | | } | |
| | | | |
| | | inline libtorrent::address policy::peer::address() const | |
| | | { | |
| | | #if TORRENT_USE_IPV6 | |
| | | if (is_v6_addr) | |
| | | return libtorrent::address_v6( | |
| | | static_cast<policy::ipv6_peer const*>(this)- | |
| | | >addr); | |
| | | #endif | |
| | | return static_cast<policy::ipv4_peer const*>(this)->addr; | |
| | | } | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_POLICY_HPP_INCLUDED | | #endif // TORRENT_POLICY_HPP_INCLUDED | |
| | | | |
End of changes. 31 change blocks. |
| 81 lines changed or deleted | | 246 lines changed or added | |
|
| session.hpp | | session.hpp | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_SESSION_HPP_INCLUDED | | #ifndef TORRENT_SESSION_HPP_INCLUDED | |
| #define TORRENT_SESSION_HPP_INCLUDED | | #define TORRENT_SESSION_HPP_INCLUDED | |
| | | | |
|
| #include <ctime> | | | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
|
| #include <set> | | | |
| #include <list> | | | |
| #include <deque> | | | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/limits.hpp> | | #include <boost/limits.hpp> | |
|
| #include <boost/tuple/tuple.hpp> | | | |
| #include <boost/filesystem/path.hpp> | | #include <boost/filesystem/path.hpp> | |
| #include <boost/thread.hpp> | | #include <boost/thread.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/entry.hpp" | | #include "libtorrent/entry.hpp" | |
|
| #include "libtorrent/alert.hpp" | | | |
| #include "libtorrent/session_status.hpp" | | #include "libtorrent/session_status.hpp" | |
| #include "libtorrent/version.hpp" | | #include "libtorrent/version.hpp" | |
| #include "libtorrent/fingerprint.hpp" | | #include "libtorrent/fingerprint.hpp" | |
|
| #include "libtorrent/time.hpp" | | | |
| #include "libtorrent/disk_io_thread.hpp" | | #include "libtorrent/disk_io_thread.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
|
| | | #include "libtorrent/alert.hpp" | |
| | | | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
|
| | | #include <boost/preprocessor/cat.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| # include <eh.h> | | # include <eh.h> | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| struct torrent_plugin; | | struct torrent_plugin; | |
| class torrent; | | class torrent; | |
|
| struct ip_filter; | | class ip_filter; | |
| class port_filter; | | class port_filter; | |
| class connection_queue; | | class connection_queue; | |
| class natpmp; | | class natpmp; | |
| class upnp; | | class upnp; | |
|
| | | class alert; | |
| | | | |
| | | // this is used to create linker errors when trying to link to | |
| | | // a library with a conflicting build configuration than the applica | |
| | | tion | |
| | | #ifdef TORRENT_DEBUG | |
| | | #define G _release | |
| | | #else | |
| | | #define G _debug | |
| | | #endif | |
| | | | |
| | | #ifdef TORRENT_USE_OPENSSL | |
| | | #define S _ssl | |
| | | #else | |
| | | #define S _nossl | |
| | | #endif | |
| | | | |
| | | #ifdef TORRENT_DISABLE_DHT | |
| | | #define D _nodht | |
| | | #else | |
| | | #define D _dht | |
| | | #endif | |
| | | | |
| | | #ifdef TORRENT_DISABLE_POOL_ALLOCATOR | |
| | | #define P _nopoolalloc | |
| | | #else | |
| | | #define P _poolalloc | |
| | | #endif | |
| | | | |
| | | #define TORRENT_LINK_TEST_PREFIX libtorrent_build_config | |
| | | #define TORRENT_LINK_TEST_NAME BOOST_PP_CAT(TORRENT_LINK_TEST_PREFIX, BOOST | |
| | | _PP_CAT(P, BOOST_PP_CAT(D, BOOST_PP_CAT(S, G)))) | |
| | | #undef P | |
| | | #undef D | |
| | | #undef S | |
| | | #undef G | |
| | | | |
| | | inline void test_link() | |
| | | { | |
| | | extern void TORRENT_LINK_TEST_NAME(); | |
| | | TORRENT_LINK_TEST_NAME(); | |
| | | } | |
| | | | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| | | | |
|
| | | session_settings min_memory_usage(); | |
| | | session_settings high_performance_seed(); | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
| // workaround for microsofts | | // workaround for microsofts | |
| // hardware exceptions that makes | | // hardware exceptions that makes | |
| // it hard to debug stuff | | // it hard to debug stuff | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| struct eh_initializer | | struct eh_initializer | |
| { | | { | |
| eh_initializer() | | eh_initializer() | |
| { | | { | |
| | | | |
| skipping to change at line 136 | | skipping to change at line 174 | |
| add_torrent_params(storage_constructor_type sc = default_sto
rage_constructor) | | add_torrent_params(storage_constructor_type sc = default_sto
rage_constructor) | |
| : tracker_url(0) | | : tracker_url(0) | |
| , name(0) | | , name(0) | |
| , resume_data(0) | | , resume_data(0) | |
| , storage_mode(storage_mode_sparse) | | , storage_mode(storage_mode_sparse) | |
| , paused(true) | | , paused(true) | |
| , auto_managed(true) | | , auto_managed(true) | |
| , duplicate_is_error(false) | | , duplicate_is_error(false) | |
| , storage(sc) | | , storage(sc) | |
| , userdata(0) | | , userdata(0) | |
|
| | | , seed_mode(false) | |
| | | , override_resume_data(false) | |
| | | , upload_mode(false) | |
| {} | | {} | |
| | | | |
| boost::intrusive_ptr<torrent_info> ti; | | boost::intrusive_ptr<torrent_info> ti; | |
| char const* tracker_url; | | char const* tracker_url; | |
| sha1_hash info_hash; | | sha1_hash info_hash; | |
| char const* name; | | char const* name; | |
| fs::path save_path; | | fs::path save_path; | |
| std::vector<char>* resume_data; | | std::vector<char>* resume_data; | |
| storage_mode_t storage_mode; | | storage_mode_t storage_mode; | |
| bool paused; | | bool paused; | |
| bool auto_managed; | | bool auto_managed; | |
| bool duplicate_is_error; | | bool duplicate_is_error; | |
| storage_constructor_type storage; | | storage_constructor_type storage; | |
| void* userdata; | | void* userdata; | |
|
| | | bool seed_mode; | |
| | | bool override_resume_data; | |
| | | bool upload_mode; | |
| }; | | }; | |
| | | | |
| class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_ini
tializer | | class TORRENT_EXPORT session: public boost::noncopyable, aux::eh_ini
tializer | |
| { | | { | |
| public: | | public: | |
| | | | |
| session(fingerprint const& print = fingerprint("LT" | | session(fingerprint const& print = fingerprint("LT" | |
| , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR
, 0, 0) | | , LIBTORRENT_VERSION_MAJOR, LIBTORRENT_VERSION_MINOR
, 0, 0) | |
| , int flags = start_default_features | add_default_p
lugins | | , int flags = start_default_features | add_default_p
lugins | |
|
| | | , int alert_mask = alert::error_notification | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| , fs::path logpath = "." | | , fs::path logpath = "." | |
| #endif | | #endif | |
| ); | | ); | |
| session( | | session( | |
| fingerprint const& print | | fingerprint const& print | |
| , std::pair<int, int> listen_port_range | | , std::pair<int, int> listen_port_range | |
| , char const* listen_interface = "0.0.0.0" | | , char const* listen_interface = "0.0.0.0" | |
| , int flags = start_default_features | add_default_p
lugins | | , int flags = start_default_features | add_default_p
lugins | |
|
| | | , int alert_mask = alert::error_notification | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| , fs::path logpath = "." | | , fs::path logpath = "." | |
| #endif | | #endif | |
| ); | | ); | |
| | | | |
| ~session(); | | ~session(); | |
| | | | |
|
| | | enum save_state_flags_t | |
| | | { | |
| | | save_settings = 0x001, | |
| | | save_dht_settings = 0x002, | |
| | | save_dht_proxy = 0x004, | |
| | | save_dht_state = 0x008, | |
| | | save_i2p_proxy = 0x010, | |
| | | save_encryption_settings = 0x020, | |
| | | save_peer_proxy = 0x040, | |
| | | save_web_proxy = 0x080, | |
| | | save_tracker_proxy = 0x100, | |
| | | save_as_map = 0x200, | |
| | | }; | |
| | | void save_state(entry& e, boost::uint32_t flags = 0xffffffff | |
| | | ) const; | |
| | | void load_state(lazy_entry const& e); | |
| | | | |
| // returns a list of all torrents in this session | | // returns a list of all torrents in this session | |
| std::vector<torrent_handle> get_torrents() const; | | std::vector<torrent_handle> get_torrents() const; | |
| | | | |
|
| | | io_service& get_io_service(); | |
| | | | |
| // returns an invalid handle in case the torrent doesn't exi
st | | // returns an invalid handle in case the torrent doesn't exi
st | |
| torrent_handle find_torrent(sha1_hash const& info_hash) cons
t; | | torrent_handle find_torrent(sha1_hash const& info_hash) cons
t; | |
| | | | |
| // all torrent_handles must be destructed before the session
is destructed! | | // all torrent_handles must be destructed before the session
is destructed! | |
| torrent_handle add_torrent(add_torrent_params const& params)
; | | torrent_handle add_torrent(add_torrent_params const& params)
; | |
|
| | | torrent_handle add_torrent(add_torrent_params const& params,
error_code& ec); | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| torrent_handle add_torrent( | | torrent_handle add_torrent( | |
| torrent_info const& ti | | torrent_info const& ti | |
| , fs::path const& save_path | | , fs::path const& save_path | |
| , entry const& resume_data = entry() | | , entry const& resume_data = entry() | |
| , storage_mode_t storage_mode = storage_mode_sparse | | , storage_mode_t storage_mode = storage_mode_sparse | |
| , bool paused = false | | , bool paused = false | |
| , storage_constructor_type sc = default_storage_cons
tructor) TORRENT_DEPRECATED; | | , storage_constructor_type sc = default_storage_cons
tructor) TORRENT_DEPRECATED; | |
| | | | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| torrent_handle add_torrent( | | torrent_handle add_torrent( | |
| boost::intrusive_ptr<torrent_info> ti | | boost::intrusive_ptr<torrent_info> ti | |
| , fs::path const& save_path | | , fs::path const& save_path | |
| , entry const& resume_data = entry() | | , entry const& resume_data = entry() | |
| , storage_mode_t storage_mode = storage_mode_sparse | | , storage_mode_t storage_mode = storage_mode_sparse | |
| , bool paused = false | | , bool paused = false | |
| , storage_constructor_type sc = default_storage_cons
tructor | | , storage_constructor_type sc = default_storage_cons
tructor | |
| , void* userdata = 0) TORRENT_DEPRECATED; | | , void* userdata = 0) TORRENT_DEPRECATED; | |
| | | | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| torrent_handle add_torrent( | | torrent_handle add_torrent( | |
| char const* tracker_url | | char const* tracker_url | |
| , sha1_hash const& info_hash | | , sha1_hash const& info_hash | |
| , char const* name | | , char const* name | |
| , fs::path const& save_path | | , fs::path const& save_path | |
| , entry const& resume_data = entry() | | , entry const& resume_data = entry() | |
| , storage_mode_t storage_mode = storage_mode_sparse | | , storage_mode_t storage_mode = storage_mode_sparse | |
| , bool paused = false | | , bool paused = false | |
| , storage_constructor_type sc = default_storage_cons
tructor | | , storage_constructor_type sc = default_storage_cons
tructor | |
| , void* userdata = 0) TORRENT_DEPRECATED; | | , void* userdata = 0) TORRENT_DEPRECATED; | |
| #endif | | #endif | |
|
| | | #endif | |
| | | | |
| session_proxy abort() { return session_proxy(m_impl); } | | session_proxy abort() { return session_proxy(m_impl); } | |
| | | | |
| void pause(); | | void pause(); | |
| void resume(); | | void resume(); | |
| bool is_paused() const; | | bool is_paused() const; | |
| | | | |
| session_status status() const; | | session_status status() const; | |
| cache_status get_cache_status() const; | | cache_status get_cache_status() const; | |
| | | | |
| void get_cache_info(sha1_hash const& ih | | void get_cache_info(sha1_hash const& ih | |
| , std::vector<cached_piece_info>& ret) const; | | , std::vector<cached_piece_info>& ret) const; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
|
| void start_dht(entry const& startup_state = entry()); | | void start_dht(); | |
| void stop_dht(); | | void stop_dht(); | |
| void set_dht_settings(dht_settings const& settings); | | void set_dht_settings(dht_settings const& settings); | |
|
| entry dht_state() const; | | #ifndef TORRENT_NO_DEPRECATE | |
| | | // deprecated in 0.15 | |
| | | // use save_state and load_state instead | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | entry dht_state() const TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void start_dht(entry const& startup_state) TORRENT_DEPRECATE | |
| | | D; | |
| | | #endif | |
| void add_dht_node(std::pair<std::string, int> const& node); | | void add_dht_node(std::pair<std::string, int> const& node); | |
| void add_dht_router(std::pair<std::string, int> const& node)
; | | void add_dht_router(std::pair<std::string, int> const& node)
; | |
|
| | | bool is_dht_running() const; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| void set_pe_settings(pe_settings const& settings); | | void set_pe_settings(pe_settings const& settings); | |
| pe_settings const& get_pe_settings() const; | | pe_settings const& get_pe_settings() const; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> ext); | | void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> ext); | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| int as_for_ip(address const& addr); | | int as_for_ip(address const& addr); | |
| bool load_asnum_db(char const* file); | | bool load_asnum_db(char const* file); | |
| bool load_country_db(char const* file); | | bool load_country_db(char const* file); | |
|
| | | #ifndef BOOST_FILESYSTEM_NARROW_ONLY | |
| | | bool load_country_db(wchar_t const* file); | |
| | | bool load_asnum_db(wchar_t const* file); | |
| | | #endif | |
| #endif | | #endif | |
| | | | |
|
| void load_state(entry const& ses_state); | | #ifndef TORRENT_NO_DEPRECATE | |
| entry state() const; | | // deprecated in 0.15 | |
| | | // use load_state and save_state instead | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | void load_state(entry const& ses_state) TORRENT_DEPRECATED; | |
| | | TORRENT_DEPRECATED_PREFIX | |
| | | entry state() const TORRENT_DEPRECATED; | |
| | | #endif | |
| | | | |
| void set_ip_filter(ip_filter const& f); | | void set_ip_filter(ip_filter const& f); | |
| ip_filter const& get_ip_filter() const; | | ip_filter const& get_ip_filter() const; | |
| | | | |
| void set_port_filter(port_filter const& f); | | void set_port_filter(port_filter const& f); | |
| void set_peer_id(peer_id const& pid); | | void set_peer_id(peer_id const& pid); | |
| void set_key(int key); | | void set_key(int key); | |
| peer_id id() const; | | peer_id id() const; | |
| | | | |
| bool is_listening() const; | | bool is_listening() const; | |
| | | | |
| skipping to change at line 323 | | skipping to change at line 411 | |
| proxy_settings const& web_seed_proxy() const; | | proxy_settings const& web_seed_proxy() const; | |
| proxy_settings const& tracker_proxy() const; | | proxy_settings const& tracker_proxy() const; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| void set_dht_proxy(proxy_settings const& s); | | void set_dht_proxy(proxy_settings const& s); | |
| proxy_settings const& dht_proxy() const; | | proxy_settings const& dht_proxy() const; | |
| #endif | | #endif | |
| | | | |
| int upload_rate_limit() const; | | int upload_rate_limit() const; | |
| int download_rate_limit() const; | | int download_rate_limit() const; | |
|
| | | int local_upload_rate_limit() const; | |
| | | int local_download_rate_limit() const; | |
| int max_half_open_connections() const; | | int max_half_open_connections() const; | |
| | | | |
|
| | | void set_local_upload_rate_limit(int bytes_per_second); | |
| | | void set_local_download_rate_limit(int bytes_per_second); | |
| void set_upload_rate_limit(int bytes_per_second); | | void set_upload_rate_limit(int bytes_per_second); | |
| void set_download_rate_limit(int bytes_per_second); | | void set_download_rate_limit(int bytes_per_second); | |
| void set_max_uploads(int limit); | | void set_max_uploads(int limit); | |
| void set_max_connections(int limit); | | void set_max_connections(int limit); | |
| void set_max_half_open_connections(int limit); | | void set_max_half_open_connections(int limit); | |
| | | | |
|
| | | int max_connections() const; | |
| | | int max_uploads() const; | |
| | | | |
| std::auto_ptr<alert> pop_alert(); | | std::auto_ptr<alert> pop_alert(); | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| void set_severity_level(alert::severity_t s) TORRENT_DEPRECA
TED; | | void set_severity_level(alert::severity_t s) TORRENT_DEPRECA
TED; | |
| #endif | | #endif | |
| void set_alert_mask(int m); | | void set_alert_mask(int m); | |
| size_t set_alert_queue_size_limit(size_t queue_size_limit_); | | size_t set_alert_queue_size_limit(size_t queue_size_limit_); | |
| | | | |
| alert const* wait_for_alert(time_duration max_wait); | | alert const* wait_for_alert(time_duration max_wait); | |
|
| | | void set_alert_dispatch(boost::function<void(alert const&)>
const& fun); | |
| | | | |
| connection_queue& get_connection_queue(); | | connection_queue& get_connection_queue(); | |
| | | | |
| // starts/stops UPnP, NATPMP or LSD port mappers | | // starts/stops UPnP, NATPMP or LSD port mappers | |
| // they are stopped by default | | // they are stopped by default | |
| void start_lsd(); | | void start_lsd(); | |
| natpmp* start_natpmp(); | | natpmp* start_natpmp(); | |
| upnp* start_upnp(); | | upnp* start_upnp(); | |
| | | | |
| void stop_lsd(); | | void stop_lsd(); | |
| | | | |
End of changes. 32 change blocks. |
| 12 lines changed or deleted | | 113 lines changed or added | |
|
| session_impl.hpp | | session_impl.hpp | |
| | | | |
| skipping to change at line 36 | | skipping to change at line 36 | |
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_SESSION_IMPL_HPP_INCLUDED | | #ifndef TORRENT_SESSION_IMPL_HPP_INCLUDED | |
| #define TORRENT_SESSION_IMPL_HPP_INCLUDED | | #define TORRENT_SESSION_IMPL_HPP_INCLUDED | |
| | | | |
|
| #include <ctime> | | | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| #include <set> | | #include <set> | |
| #include <list> | | #include <list> | |
|
| #include <deque> | | | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| #ifdef WITH_SHIPPED_GEOIP_H | | #ifdef WITH_SHIPPED_GEOIP_H | |
| #include "libtorrent/GeoIP.h" | | #include "libtorrent/GeoIP.h" | |
| #else | | #else | |
| #include <GeoIP.h> | | #include <GeoIP.h> | |
| #endif | | #endif | |
| #endif | | #endif | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
|
| #include <boost/limits.hpp> | | | |
| #include <boost/tuple/tuple.hpp> | | | |
| #include <boost/filesystem/path.hpp> | | #include <boost/filesystem/path.hpp> | |
| #include <boost/thread.hpp> | | #include <boost/thread.hpp> | |
|
| #include <boost/thread/recursive_mutex.hpp> | | | |
| #include <boost/thread/condition.hpp> | | #include <boost/thread/condition.hpp> | |
|
| | | #include <boost/pool/object_pool.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/torrent_handle.hpp" | | #include "libtorrent/torrent_handle.hpp" | |
| #include "libtorrent/entry.hpp" | | #include "libtorrent/entry.hpp" | |
| #include "libtorrent/socket.hpp" | | #include "libtorrent/socket.hpp" | |
| #include "libtorrent/peer_id.hpp" | | #include "libtorrent/peer_id.hpp" | |
| #include "libtorrent/tracker_manager.hpp" | | #include "libtorrent/tracker_manager.hpp" | |
|
| #include "libtorrent/alert.hpp" | | | |
| #include "libtorrent/debug.hpp" | | #include "libtorrent/debug.hpp" | |
| #include "libtorrent/piece_block_progress.hpp" | | #include "libtorrent/piece_block_progress.hpp" | |
| #include "libtorrent/ip_filter.hpp" | | #include "libtorrent/ip_filter.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/session_settings.hpp" | | #include "libtorrent/session_settings.hpp" | |
| #include "libtorrent/session_status.hpp" | | #include "libtorrent/session_status.hpp" | |
| #include "libtorrent/session.hpp" | | #include "libtorrent/session.hpp" | |
| #include "libtorrent/stat.hpp" | | #include "libtorrent/stat.hpp" | |
| #include "libtorrent/file_pool.hpp" | | #include "libtorrent/file_pool.hpp" | |
| #include "libtorrent/bandwidth_manager.hpp" | | #include "libtorrent/bandwidth_manager.hpp" | |
| #include "libtorrent/socket_type.hpp" | | #include "libtorrent/socket_type.hpp" | |
| #include "libtorrent/connection_queue.hpp" | | #include "libtorrent/connection_queue.hpp" | |
| #include "libtorrent/disk_io_thread.hpp" | | #include "libtorrent/disk_io_thread.hpp" | |
|
| #include "libtorrent/assert.hpp" | | | |
| #include "libtorrent/udp_socket.hpp" | | #include "libtorrent/udp_socket.hpp" | |
|
| | | #include "libtorrent/assert.hpp" | |
| | | #include "libtorrent/policy.hpp" // for policy::peer | |
| | | #include "libtorrent/alert.hpp" // for alert_manager | |
| | | | |
| #if TORRENT_COMPLETE_TYPES_REQUIRED | | #if TORRENT_COMPLETE_TYPES_REQUIRED | |
| #include "libtorrent/peer_connection.hpp" | | #include "libtorrent/peer_connection.hpp" | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| | | | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| class peer_connection; | | class peer_connection; | |
| class upnp; | | class upnp; | |
| class natpmp; | | class natpmp; | |
| class lsd; | | class lsd; | |
| struct fingerprint; | | struct fingerprint; | |
|
| | | class torrent; | |
| | | class alert; | |
| | | | |
| namespace dht | | namespace dht | |
| { | | { | |
|
| class dht_tracker; | | struct dht_tracker; | |
| } | | } | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
| | | | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| struct tracker_logger; | | struct tracker_logger; | |
| #endif | | #endif | |
| | | | |
|
| | | // used to initialize the g_current_time before | |
| | | // anything else | |
| | | struct initialize_timer | |
| | | { | |
| | | initialize_timer(); | |
| | | }; | |
| | | | |
| // this is the link between the main thread and the | | // this is the link between the main thread and the | |
| // thread started to run the main downloader loop | | // thread started to run the main downloader loop | |
|
| struct session_impl: boost::noncopyable | | struct session_impl: boost::noncopyable, initialize_timer | |
| { | | { | |
| | | | |
| // the size of each allocation that is chained in th
e send buffer | | // the size of each allocation that is chained in th
e send buffer | |
|
| enum { send_buffer_size = 200 }; | | enum { send_buffer_size = 128 }; | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| friend class ::libtorrent::peer_connection; | | friend class ::libtorrent::peer_connection; | |
| #endif | | #endif | |
| friend struct checker_impl; | | friend struct checker_impl; | |
| friend class invariant_access; | | friend class invariant_access; | |
| typedef std::set<boost::intrusive_ptr<peer_connectio
n> > connection_map; | | typedef std::set<boost::intrusive_ptr<peer_connectio
n> > connection_map; | |
| typedef std::map<sha1_hash, boost::shared_ptr<torren
t> > torrent_map; | | typedef std::map<sha1_hash, boost::shared_ptr<torren
t> > torrent_map; | |
| | | | |
| session_impl( | | session_impl( | |
| | | | |
| skipping to change at line 164 | | skipping to change at line 170 | |
| | | | |
| void open_listen_port(); | | void open_listen_port(); | |
| | | | |
| // if we are listening on an IPv6 interface | | // if we are listening on an IPv6 interface | |
| // this will return one of the IPv6 addresses on thi
s | | // this will return one of the IPv6 addresses on thi
s | |
| // machine, otherwise just an empty endpoint | | // machine, otherwise just an empty endpoint | |
| tcp::endpoint get_ipv6_interface() const; | | tcp::endpoint get_ipv6_interface() const; | |
| tcp::endpoint get_ipv4_interface() const; | | tcp::endpoint get_ipv4_interface() const; | |
| | | | |
| void async_accept(boost::shared_ptr<socket_acceptor>
const& listener); | | void async_accept(boost::shared_ptr<socket_acceptor>
const& listener); | |
|
| void on_incoming_connection(boost::shared_ptr<socket
_type> const& s | | void on_accept_connection(boost::shared_ptr<socket_t
ype> const& s | |
| , boost::weak_ptr<socket_acceptor> listener,
error_code const& e); | | , boost::weak_ptr<socket_acceptor> listener,
error_code const& e); | |
|
| | | void on_socks_accept(boost::shared_ptr<socket_type> | |
| | | const& s | |
| | | , error_code const& e); | |
| | | | |
| | | void incoming_connection(boost::shared_ptr<socket_ty | |
| | | pe> const& s); | |
| | | | |
| // must be locked to access the data | | // must be locked to access the data | |
| // in this struct | | // in this struct | |
|
| typedef boost::recursive_mutex mutex_t; | | typedef boost::mutex mutex_t; | |
| mutable mutex_t m_mutex; | | mutable mutex_t m_mutex; | |
| | | | |
| boost::weak_ptr<torrent> find_torrent(const sha1_has
h& info_hash); | | boost::weak_ptr<torrent> find_torrent(const sha1_has
h& info_hash); | |
| peer_id const& get_peer_id() const { return m_peer_i
d; } | | peer_id const& get_peer_id() const { return m_peer_i
d; } | |
| | | | |
|
| void close_connection(peer_connection const* p | | void close_connection(peer_connection const* p, erro | |
| , char const* message); | | r_code const& ec); | |
| | | | |
| void set_settings(session_settings const& s); | | void set_settings(session_settings const& s); | |
| session_settings const& settings() const { return m_
settings; } | | session_settings const& settings() const { return m_
settings; } | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| void add_dht_node(std::pair<std::string, int> const&
node); | | void add_dht_node(std::pair<std::string, int> const&
node); | |
| void add_dht_node(udp::endpoint n); | | void add_dht_node(udp::endpoint n); | |
| void add_dht_router(std::pair<std::string, int> cons
t& node); | | void add_dht_router(std::pair<std::string, int> cons
t& node); | |
| void set_dht_settings(dht_settings const& s); | | void set_dht_settings(dht_settings const& s); | |
| dht_settings const& get_dht_settings() const { retur
n m_dht_settings; } | | dht_settings const& get_dht_settings() const { retur
n m_dht_settings; } | |
|
| void start_dht(entry const& startup_state); | | void start_dht(); | |
| void stop_dht(); | | void stop_dht(); | |
|
| | | void start_dht(entry const& startup_state); | |
| | | | |
|
| entry dht_state() const; | | #ifndef TORRENT_NO_DEPRECATE | |
| | | entry dht_state(session_impl::mutex_t::scoped_lock& | |
| | | l) const; | |
| | | #endif | |
| | | void maybe_update_udp_mapping(int nat, int local_por | |
| | | t, int external_port); | |
| void on_dht_router_name_lookup(error_code const& e | | void on_dht_router_name_lookup(error_code const& e | |
| , tcp::resolver::iterator host); | | , tcp::resolver::iterator host); | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| void set_pe_settings(pe_settings const& settings); | | void set_pe_settings(pe_settings const& settings); | |
| pe_settings const& get_pe_settings() const { return
m_pe_settings; } | | pe_settings const& get_pe_settings() const { return
m_pe_settings; } | |
| #endif | | #endif | |
| | | | |
|
| | | void on_port_map_log(char const* msg, int map_transp | |
| | | ort); | |
| | | | |
| | | void on_lsd_announce(error_code const& e); | |
| | | | |
| // called when a port mapping is successful, or a ro
uter returns | | // called when a port mapping is successful, or a ro
uter returns | |
| // a failure to map a port | | // a failure to map a port | |
|
| void on_port_mapping(int mapping, int port, std::str
ing const& errmsg | | void on_port_mapping(int mapping, int port, error_co
de const& ec | |
| , int nat_transport); | | , int nat_transport); | |
| | | | |
| bool is_aborted() const { return m_abort; } | | bool is_aborted() const { return m_abort; } | |
| bool is_paused() const { return m_paused; } | | bool is_paused() const { return m_paused; } | |
| | | | |
| void pause(); | | void pause(); | |
| void resume(); | | void resume(); | |
| | | | |
| void set_ip_filter(ip_filter const& f); | | void set_ip_filter(ip_filter const& f); | |
| ip_filter const& get_ip_filter() const; | | ip_filter const& get_ip_filter() const; | |
| | | | |
| void set_port_filter(port_filter const& f); | | void set_port_filter(port_filter const& f); | |
| | | | |
| bool listen_on( | | bool listen_on( | |
| std::pair<int, int> const& port_range | | std::pair<int, int> const& port_range | |
| , const char* net_interface = 0); | | , const char* net_interface = 0); | |
| bool is_listening() const; | | bool is_listening() const; | |
| | | | |
|
| torrent_handle add_torrent(add_torrent_params const&
); | | torrent_handle add_torrent(add_torrent_params const&
, error_code& ec); | |
| | | | |
| void remove_torrent(torrent_handle const& h, int opt
ions); | | void remove_torrent(torrent_handle const& h, int opt
ions); | |
| | | | |
| std::vector<torrent_handle> get_torrents(); | | std::vector<torrent_handle> get_torrents(); | |
| | | | |
|
| void check_torrent(boost::shared_ptr<torrent> const& | | void queue_check_torrent(boost::shared_ptr<torrent> | |
| t); | | const& t); | |
| void done_checking(boost::shared_ptr<torrent> const& | | void dequeue_check_torrent(boost::shared_ptr<torrent | |
| t); | | > const& t); | |
| | | | |
| void set_alert_mask(int m); | | void set_alert_mask(int m); | |
| size_t set_alert_queue_size_limit(size_t queue_size_
limit_); | | size_t set_alert_queue_size_limit(size_t queue_size_
limit_); | |
| std::auto_ptr<alert> pop_alert(); | | std::auto_ptr<alert> pop_alert(); | |
|
| | | void set_alert_dispatch(boost::function<void(alert c
onst&)> const&); | |
| | | | |
| alert const* wait_for_alert(time_duration max_wait); | | alert const* wait_for_alert(time_duration max_wait); | |
| | | | |
| int upload_rate_limit() const; | | int upload_rate_limit() const; | |
| int download_rate_limit() const; | | int download_rate_limit() const; | |
|
| | | int local_upload_rate_limit() const; | |
| | | int local_download_rate_limit() const; | |
| | | | |
| | | void set_local_download_rate_limit(int bytes_per_sec | |
| | | ond); | |
| | | void set_local_upload_rate_limit(int bytes_per_secon | |
| | | d); | |
| | | | |
| void set_download_rate_limit(int bytes_per_second); | | void set_download_rate_limit(int bytes_per_second); | |
| void set_upload_rate_limit(int bytes_per_second); | | void set_upload_rate_limit(int bytes_per_second); | |
| void set_max_half_open_connections(int limit); | | void set_max_half_open_connections(int limit); | |
| void set_max_connections(int limit); | | void set_max_connections(int limit); | |
| void set_max_uploads(int limit); | | void set_max_uploads(int limit); | |
| | | | |
| int max_connections() const { return m_max_connectio
ns; } | | int max_connections() const { return m_max_connectio
ns; } | |
| int max_uploads() const { return m_max_uploads; } | | int max_uploads() const { return m_max_uploads; } | |
| int max_half_open_connections() const { return m_hal
f_open.limit(); } | | int max_half_open_connections() const { return m_hal
f_open.limit(); } | |
| | | | |
| int num_uploads() const { return m_num_unchoked; } | | int num_uploads() const { return m_num_unchoked; } | |
| int num_connections() const | | int num_connections() const | |
| { return m_connections.size(); } | | { return m_connections.size(); } | |
| | | | |
| void unchoke_peer(peer_connection& c); | | void unchoke_peer(peer_connection& c); | |
|
| | | void choke_peer(peer_connection& c); | |
| | | | |
| session_status status() const; | | session_status status() const; | |
| void set_peer_id(peer_id const& id); | | void set_peer_id(peer_id const& id); | |
| void set_key(int key); | | void set_key(int key); | |
| unsigned short listen_port() const; | | unsigned short listen_port() const; | |
| | | | |
| void abort(); | | void abort(); | |
| | | | |
| torrent_handle find_torrent_handle(sha1_hash const&
info_hash); | | torrent_handle find_torrent_handle(sha1_hash const&
info_hash); | |
| | | | |
| void announce_lsd(sha1_hash const& ih); | | void announce_lsd(sha1_hash const& ih); | |
| | | | |
|
| | | void save_state(entry& e, boost::uint32_t flags, ses | |
| | | sion_impl::mutex_t::scoped_lock& l) const; | |
| | | void load_state(lazy_entry const& e); | |
| | | | |
| void set_peer_proxy(proxy_settings const& s) | | void set_peer_proxy(proxy_settings const& s) | |
|
| { m_peer_proxy = s; } | | { | |
| | | m_peer_proxy = s; | |
| | | // in case we just set a socks proxy, we mig | |
| | | ht have to | |
| | | // open the socks incoming connection | |
| | | if (!m_socks_listen_socket) open_new_incomin | |
| | | g_socks_connection(); | |
| | | } | |
| void set_web_seed_proxy(proxy_settings const& s) | | void set_web_seed_proxy(proxy_settings const& s) | |
| { m_web_seed_proxy = s; } | | { m_web_seed_proxy = s; } | |
| void set_tracker_proxy(proxy_settings const& s) | | void set_tracker_proxy(proxy_settings const& s) | |
| { m_tracker_proxy = s; } | | { m_tracker_proxy = s; } | |
| | | | |
| proxy_settings const& peer_proxy() const | | proxy_settings const& peer_proxy() const | |
| { return m_peer_proxy; } | | { return m_peer_proxy; } | |
| proxy_settings const& web_seed_proxy() const | | proxy_settings const& web_seed_proxy() const | |
| { return m_web_seed_proxy; } | | { return m_web_seed_proxy; } | |
| proxy_settings const& tracker_proxy() const | | proxy_settings const& tracker_proxy() const | |
| | | | |
| skipping to change at line 300 | | skipping to change at line 332 | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| std::string as_name_for_ip(address const& a); | | std::string as_name_for_ip(address const& a); | |
| int as_for_ip(address const& a); | | int as_for_ip(address const& a); | |
| std::pair<const int, int>* lookup_as(int as); | | std::pair<const int, int>* lookup_as(int as); | |
| bool load_asnum_db(char const* file); | | bool load_asnum_db(char const* file); | |
| bool has_asnum_db() const { return m_asnum_db; } | | bool has_asnum_db() const { return m_asnum_db; } | |
| | | | |
| bool load_country_db(char const* file); | | bool load_country_db(char const* file); | |
| bool has_country_db() const { return m_country_db; } | | bool has_country_db() const { return m_country_db; } | |
| char const* country_for_ip(address const& a); | | char const* country_for_ip(address const& a); | |
|
| | | | |
| | | #ifndef BOOST_FILESYSTEM_NARROW_ONLY | |
| | | bool load_asnum_db(wchar_t const* file); | |
| | | bool load_country_db(wchar_t const* file); | |
| | | #endif | |
| #endif | | #endif | |
| | | | |
| void load_state(entry const& ses_state); | | void load_state(entry const& ses_state); | |
| entry state() const; | | entry state() const; | |
| | | | |
| void start_lsd(); | | void start_lsd(); | |
|
| natpmp* start_natpmp(); | | void start_natpmp(natpmp* n); | |
| upnp* start_upnp(); | | void start_upnp(upnp* u); | |
| | | | |
| void stop_lsd(); | | void stop_lsd(); | |
| void stop_natpmp(); | | void stop_natpmp(); | |
| void stop_upnp(); | | void stop_upnp(); | |
| | | | |
| int next_port(); | | int next_port(); | |
| | | | |
| void add_redundant_bytes(size_type b) | | void add_redundant_bytes(size_type b) | |
| { | | { | |
| TORRENT_ASSERT(b > 0); | | TORRENT_ASSERT(b > 0); | |
| m_total_redundant_bytes += b; | | m_total_redundant_bytes += b; | |
| } | | } | |
| | | | |
| void add_failed_bytes(size_type b) | | void add_failed_bytes(size_type b) | |
| { | | { | |
| TORRENT_ASSERT(b > 0); | | TORRENT_ASSERT(b > 0); | |
| m_total_failed_bytes += b; | | m_total_failed_bytes += b; | |
| } | | } | |
| | | | |
|
| // handles delayed alerts | | | |
| alert_manager m_alerts; | | | |
| | | | |
| std::pair<char*, int> allocate_buffer(int size); | | std::pair<char*, int> allocate_buffer(int size); | |
| void free_buffer(char* buf, int size); | | void free_buffer(char* buf, int size); | |
| | | | |
|
| char* allocate_disk_buffer(); | | char* allocate_disk_buffer(char const* category); | |
| void free_disk_buffer(char* buf); | | void free_disk_buffer(char* buf); | |
| | | | |
| void set_external_address(address const& ip); | | void set_external_address(address const& ip); | |
| address const& external_address() const { return m_e
xternal_address; } | | address const& external_address() const { return m_e
xternal_address; } | |
| | | | |
| // private: | | // private: | |
| | | | |
|
| void dht_state_callback(boost::condition& c | | void update_disk_thread_settings(); | |
| | | void on_dht_state_callback(boost::condition& c | |
| , entry& e, bool& done) const; | | , entry& e, bool& done) const; | |
| void on_lsd_peer(tcp::endpoint peer, sha1_hash const
& ih); | | void on_lsd_peer(tcp::endpoint peer, sha1_hash const
& ih); | |
|
| | | void setup_socket_buffers(socket_type& s); | |
| | | | |
| | | // this is a shared pool where policy_peer objects | |
| | | // are allocated. It's a pool since we're likely | |
| | | // to have tens of thousands of peers, and a pool | |
| | | // saves significant overhead | |
| | | #ifdef TORRENT_STATS | |
| | | struct logging_allocator | |
| | | { | |
| | | typedef std::size_t size_type; | |
| | | typedef std::ptrdiff_t difference_type; | |
| | | | |
| | | static char* malloc(const size_type bytes) | |
| | | { | |
| | | allocated_bytes += bytes; | |
| | | ++allocations; | |
| | | return (char*)::malloc(bytes); | |
| | | } | |
| | | | |
| | | static void free(char* const block) | |
| | | { | |
| | | --allocations; | |
| | | return ::free(block); | |
| | | } | |
| | | | |
| | | static int allocations; | |
| | | static int allocated_bytes; | |
| | | }; | |
| | | boost::object_pool< | |
| | | policy::ipv4_peer, logging_allocator> m_ipv4 | |
| | | _peer_pool; | |
| | | # if TORRENT_USE_IPV6 | |
| | | boost::object_pool< | |
| | | policy::ipv6_peer, logging_allocator> m_ipv6 | |
| | | _peer_pool; | |
| | | # endif | |
| | | #else | |
| | | boost::object_pool<policy::ipv4_peer> m_ipv4_peer_po | |
| | | ol; | |
| | | # if TORRENT_USE_IPV6 | |
| | | boost::object_pool<policy::ipv6_peer> m_ipv6_peer_po | |
| | | ol; | |
| | | # endif | |
| | | #endif | |
| | | | |
| | | // this vector is used to store the block_info | |
| | | // objects pointed to by partial_piece_info returned | |
| | | // by torrent::get_download_queue. | |
| | | std::vector<block_info> m_block_info_storage; | |
| | | | |
| #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | | #ifndef TORRENT_DISABLE_POOL_ALLOCATOR | |
| // this pool is used to allocate and recycle send | | // this pool is used to allocate and recycle send | |
| // buffers from. | | // buffers from. | |
| boost::pool<> m_send_buffers; | | boost::pool<> m_send_buffers; | |
| #endif | | #endif | |
| boost::mutex m_send_buffer_mutex; | | boost::mutex m_send_buffer_mutex; | |
| | | | |
| // the file pool that all storages in this session's | | // the file pool that all storages in this session's | |
| // torrents uses. It sets a limit on the number of | | // torrents uses. It sets a limit on the number of | |
| | | | |
| skipping to change at line 367 | | skipping to change at line 447 | |
| // when they are destructed. | | // when they are destructed. | |
| file_pool m_files; | | file_pool m_files; | |
| | | | |
| // this is where all active sockets are stored. | | // this is where all active sockets are stored. | |
| // the selector can sleep while there's no activity
on | | // the selector can sleep while there's no activity
on | |
| // them | | // them | |
| mutable io_service m_io_service; | | mutable io_service m_io_service; | |
| | | | |
| tcp::resolver m_host_resolver; | | tcp::resolver m_host_resolver; | |
| | | | |
|
| | | // handles delayed alerts | |
| | | alert_manager m_alerts; | |
| | | | |
| // handles disk io requests asynchronously | | // handles disk io requests asynchronously | |
| // peers have pointers into the disk buffer | | // peers have pointers into the disk buffer | |
| // pool, and must be destructed before this | | // pool, and must be destructed before this | |
| // object. The disk thread relies on the file | | // object. The disk thread relies on the file | |
| // pool object, and must be destructed before | | // pool object, and must be destructed before | |
| // m_files. The disk io thread posts completion | | // m_files. The disk io thread posts completion | |
| // events to the io service, and needs to be | | // events to the io service, and needs to be | |
| // constructed after it. | | // constructed after it. | |
| disk_io_thread m_disk_thread; | | disk_io_thread m_disk_thread; | |
| | | | |
| // this is a list of half-open tcp connections | | // this is a list of half-open tcp connections | |
| // (only outgoing connections) | | // (only outgoing connections) | |
| // this has to be one of the last | | // this has to be one of the last | |
| // members to be destructed | | // members to be destructed | |
| connection_queue m_half_open; | | connection_queue m_half_open; | |
| | | | |
| // the bandwidth manager is responsible for | | // the bandwidth manager is responsible for | |
| // handing out bandwidth to connections that | | // handing out bandwidth to connections that | |
| // asks for it, it can also throttle the | | // asks for it, it can also throttle the | |
| // rate. | | // rate. | |
|
| bandwidth_manager<peer_connection, torrent> m_downlo | | bandwidth_manager<peer_connection> m_download_rate; | |
| ad_channel; | | bandwidth_manager<peer_connection> m_upload_rate; | |
| bandwidth_manager<peer_connection, torrent> m_upload | | | |
| _channel; | | | |
| | | | |
|
| bandwidth_manager<peer_connection, torrent>* m_bandw | | // the global rate limiter bandwidth channels | |
| idth_manager[2]; | | bandwidth_channel m_download_channel; | |
| | | bandwidth_channel m_upload_channel; | |
| | | | |
| | | // bandwidth channels for local peers when | |
| | | // rate limits are ignored. They are only | |
| | | // throttled by these global rate limiters | |
| | | // and they don't have a rate limit set by | |
| | | // default | |
| | | bandwidth_channel m_local_download_channel; | |
| | | bandwidth_channel m_local_upload_channel; | |
| | | | |
| | | bandwidth_channel* m_bandwidth_channel[2]; | |
| | | | |
| tracker_manager m_tracker_manager; | | tracker_manager m_tracker_manager; | |
| torrent_map m_torrents; | | torrent_map m_torrents; | |
| typedef std::list<boost::shared_ptr<torrent> > check
_queue_t; | | typedef std::list<boost::shared_ptr<torrent> > check
_queue_t; | |
|
| | | | |
| | | // this has all torrents that wants to be checked in | |
| | | it | |
| check_queue_t m_queued_for_checking; | | check_queue_t m_queued_for_checking; | |
| | | | |
| // this maps sockets to their peer_connection | | // this maps sockets to their peer_connection | |
| // object. It is the complete list of all connected | | // object. It is the complete list of all connected | |
| // peers. | | // peers. | |
| connection_map m_connections; | | connection_map m_connections; | |
| | | | |
| // filters incoming connections | | // filters incoming connections | |
| ip_filter m_ip_filter; | | ip_filter m_ip_filter; | |
| | | | |
| | | | |
| skipping to change at line 453 | | skipping to change at line 550 | |
| // the client is reachable through. | | // the client is reachable through. | |
| int external_port; | | int external_port; | |
| | | | |
| // the actual socket | | // the actual socket | |
| boost::shared_ptr<socket_acceptor> sock; | | boost::shared_ptr<socket_acceptor> sock; | |
| }; | | }; | |
| // since we might be listening on multiple interface
s | | // since we might be listening on multiple interface
s | |
| // we might need more than one listen socket | | // we might need more than one listen socket | |
| std::list<listen_socket_t> m_listen_sockets; | | std::list<listen_socket_t> m_listen_sockets; | |
| | | | |
|
| | | // when as a socks proxy is used for peers, also | |
| | | // listen for incoming connections on a socks connec | |
| | | tion | |
| | | boost::shared_ptr<socket_type> m_socks_listen_socket | |
| | | ; | |
| | | | |
| | | void open_new_incoming_socks_connection(); | |
| | | | |
| listen_socket_t setup_listener(tcp::endpoint ep, int
retries, bool v6_only = false); | | listen_socket_t setup_listener(tcp::endpoint ep, int
retries, bool v6_only = false); | |
| | | | |
| // the settings for the client | | // the settings for the client | |
| session_settings m_settings; | | session_settings m_settings; | |
| // the proxy settings for different | | // the proxy settings for different | |
| // kinds of connections | | // kinds of connections | |
| proxy_settings m_peer_proxy; | | proxy_settings m_peer_proxy; | |
| proxy_settings m_web_seed_proxy; | | proxy_settings m_web_seed_proxy; | |
| proxy_settings m_tracker_proxy; | | proxy_settings m_tracker_proxy; | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| proxy_settings m_dht_proxy; | | proxy_settings m_dht_proxy; | |
| #endif | | #endif | |
| | | | |
|
| | | #ifndef TORRENT_DISABLE_DHT | |
| | | entry m_dht_state; | |
| | | #endif | |
| // set to true when the session object | | // set to true when the session object | |
| // is being destructed and the thread | | // is being destructed and the thread | |
| // should exit | | // should exit | |
|
| bool m_abort; | | volatile bool m_abort; | |
| | | | |
| // is true if the session is paused | | // is true if the session is paused | |
| bool m_paused; | | bool m_paused; | |
| | | | |
| // the max number of unchoked peers as set by the us
er | | // the max number of unchoked peers as set by the us
er | |
| int m_max_uploads; | | int m_max_uploads; | |
| | | | |
| // the number of unchoked peers as set by the auto-u
nchoker | | // the number of unchoked peers as set by the auto-u
nchoker | |
| // this should always be >= m_max_uploads | | // this should always be >= m_max_uploads | |
| int m_allowed_upload_slots; | | int m_allowed_upload_slots; | |
| | | | |
| skipping to change at line 524 | | skipping to change at line 630 | |
| | | | |
| // statistics gathered from all torrents. | | // statistics gathered from all torrents. | |
| stat m_stat; | | stat m_stat; | |
| | | | |
| // is false by default and set to true when | | // is false by default and set to true when | |
| // the first incoming connection is established | | // the first incoming connection is established | |
| // this is used to know if the client is behind | | // this is used to know if the client is behind | |
| // NAT or not. | | // NAT or not. | |
| bool m_incoming_connection; | | bool m_incoming_connection; | |
| | | | |
|
| void second_tick(error_code const& e); | | void on_disk_queue(); | |
| | | void on_tick(error_code const& e); | |
| | | | |
| | | int auto_manage_torrents(std::vector<torrent*>& list | |
| | | , int hard_limit, int type_limit); | |
| void recalculate_auto_managed_torrents(); | | void recalculate_auto_managed_torrents(); | |
| void recalculate_unchoke_slots(int congested_torrent
s | | void recalculate_unchoke_slots(int congested_torrent
s | |
| , int uncongested_torrents); | | , int uncongested_torrents); | |
|
| | | void recalculate_optimistic_unchoke_slot(); | |
| | | | |
| | | ptime m_created; | |
| | | int session_time() const { return total_seconds(time | |
| | | _now() - m_created); } | |
| | | | |
| ptime m_last_tick; | | ptime m_last_tick; | |
|
| | | ptime m_last_second_tick; | |
| | | | |
| | | // the last time we went through the peers | |
| | | // to decide which ones to choke/unchoke | |
| | | ptime m_last_choke; | |
| | | | |
| // when outgoing_ports is configured, this is the | | // when outgoing_ports is configured, this is the | |
| // port we'll bind the next outgoing socket to | | // port we'll bind the next outgoing socket to | |
| int m_next_port; | | int m_next_port; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| boost::intrusive_ptr<dht::dht_tracker> m_dht; | | boost::intrusive_ptr<dht::dht_tracker> m_dht; | |
| dht_settings m_dht_settings; | | dht_settings m_dht_settings; | |
| // if this is set to true, the dht listen port | | // if this is set to true, the dht listen port | |
| // will be set to the same as the tcp listen port | | // will be set to the same as the tcp listen port | |
| // and will be synchronlized with it as it changes | | // and will be synchronlized with it as it changes | |
| // it defaults to true | | // it defaults to true | |
| bool m_dht_same_port; | | bool m_dht_same_port; | |
| | | | |
| // see m_external_listen_port. This is the same | | // see m_external_listen_port. This is the same | |
| // but for the udp port used by the DHT. | | // but for the udp port used by the DHT. | |
| int m_external_udp_port; | | int m_external_udp_port; | |
| | | | |
|
| udp_socket m_dht_socket; | | rate_limited_udp_socket m_dht_socket; | |
| | | | |
| // these are used when starting the DHT | | // these are used when starting the DHT | |
| // (and bootstrapping it), and then erased | | // (and bootstrapping it), and then erased | |
| std::list<udp::endpoint> m_dht_router_nodes; | | std::list<udp::endpoint> m_dht_router_nodes; | |
| | | | |
| void on_receive_udp(error_code const& e | | void on_receive_udp(error_code const& e | |
| , udp::endpoint const& ep, char const* buf,
int len); | | , udp::endpoint const& ep, char const* buf,
int len); | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| | | | |
| skipping to change at line 570 | | skipping to change at line 689 | |
| #endif | | #endif | |
| | | | |
| boost::intrusive_ptr<natpmp> m_natpmp; | | boost::intrusive_ptr<natpmp> m_natpmp; | |
| boost::intrusive_ptr<upnp> m_upnp; | | boost::intrusive_ptr<upnp> m_upnp; | |
| boost::intrusive_ptr<lsd> m_lsd; | | boost::intrusive_ptr<lsd> m_lsd; | |
| | | | |
| // 0 is natpmp 1 is upnp | | // 0 is natpmp 1 is upnp | |
| int m_tcp_mapping[2]; | | int m_tcp_mapping[2]; | |
| int m_udp_mapping[2]; | | int m_udp_mapping[2]; | |
| | | | |
|
| // the timer used to fire the second_tick | | // the timer used to fire the tick | |
| deadline_timer m_timer; | | deadline_timer m_timer; | |
| | | | |
|
| | | // torrents are announced on the local network in a | |
| | | // round-robin fashion. All torrents are cycled thro | |
| | | ugh | |
| | | // within the LSD announce interval (which defaults | |
| | | to | |
| | | // 5 minutes) | |
| | | torrent_map::iterator m_next_lsd_torrent; | |
| | | | |
| | | // this announce timer is used | |
| | | // by Local service discovery | |
| | | deadline_timer m_lsd_announce_timer; | |
| | | | |
| // the index of the torrent that will be offered to | | // the index of the torrent that will be offered to | |
|
| // connect to a peer next time second_tick is called
. | | // connect to a peer next time on_tick is called. | |
| // This implements a round robin. | | // This implements a round robin. | |
|
| int m_next_connect_torrent; | | torrent_map::iterator m_next_connect_torrent; | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
|
| #ifdef TORRENT_STATS | | #if defined TORRENT_STATS && defined TORRENT_DISK_STATS | |
| void log_buffer_usage(); | | void log_buffer_usage(); | |
|
| | | #endif | |
| | | | |
|
| | | #if defined TORRENT_STATS | |
| // logger used to write bandwidth usage statistics | | // logger used to write bandwidth usage statistics | |
| std::ofstream m_stats_logger; | | std::ofstream m_stats_logger; | |
| int m_second_counter; | | int m_second_counter; | |
| // used to log send buffer usage statistics | | // used to log send buffer usage statistics | |
| std::ofstream m_buffer_usage_logger; | | std::ofstream m_buffer_usage_logger; | |
| // the number of send buffers that are allocated | | // the number of send buffers that are allocated | |
| int m_buffer_allocations; | | int m_buffer_allocations; | |
| #endif | | #endif | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| boost::shared_ptr<logger> create_log(std::string con
st& name | | boost::shared_ptr<logger> create_log(std::string con
st& name | |
| | | | |
| skipping to change at line 607 | | skipping to change at line 738 | |
| // shutting down. This list is just here to keep the
m alive during | | // shutting down. This list is just here to keep the
m alive during | |
| // whe shutting down process | | // whe shutting down process | |
| std::list<boost::shared_ptr<tracker_logger> > m_trac
ker_loggers; | | std::list<boost::shared_ptr<tracker_logger> > m_trac
ker_loggers; | |
| | | | |
| fs::path m_logpath; | | fs::path m_logpath; | |
| public: | | public: | |
| boost::shared_ptr<logger> m_logger; | | boost::shared_ptr<logger> m_logger; | |
| private: | | private: | |
| | | | |
| #endif | | #endif | |
|
| | | #ifdef TORRENT_UPNP_LOGGING | |
| | | std::ofstream m_upnp_log; | |
| | | #endif | |
| address m_external_address; | | address m_external_address; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| typedef std::list<boost::function<boost::shared_ptr< | | typedef std::list<boost::function<boost::shared_ptr< | |
| torrent_plugin>(torrent*, void*)> > extensio
n_list_t; | | torrent_plugin>(torrent*, void*)> > extensio
n_list_t; | |
| | | | |
| extension_list_t m_extensions; | | extension_list_t m_extensions; | |
| #endif | | #endif | |
| | | | |
| #ifndef TORRENT_DISABLE_GEO_IP | | #ifndef TORRENT_DISABLE_GEO_IP | |
| | | | |
| skipping to change at line 646 | | skipping to change at line 780 | |
| struct tracker_logger : request_callback | | struct tracker_logger : request_callback | |
| { | | { | |
| tracker_logger(session_impl& ses): m_ses(ses) {} | | tracker_logger(session_impl& ses): m_ses(ses) {} | |
| void tracker_warning(tracker_request const& req | | void tracker_warning(tracker_request const& req | |
| , std::string const& str) | | , std::string const& str) | |
| { | | { | |
| debug_log("*** tracker warning: " + str); | | debug_log("*** tracker warning: " + str); | |
| } | | } | |
| | | | |
| void tracker_response(tracker_request const& | | void tracker_response(tracker_request const& | |
|
| | | , libtorrent::address const& tracker_ip | |
| | | , std::list<address> const& ip_list | |
| , std::vector<peer_entry>& peers | | , std::vector<peer_entry>& peers | |
| , int interval | | , int interval | |
|
| | | , int min_interval | |
| , int complete | | , int complete | |
| , int incomplete | | , int incomplete | |
| , address const& external_ip) | | , address const& external_ip) | |
| { | | { | |
|
| std::stringstream s; | | std::string s; | |
| s << "TRACKER RESPONSE:\n" | | s = "TRACKER RESPONSE:\n"; | |
| "interval: " << interval << "\n" | | char tmp[200]; | |
| "peers:\n"; | | snprintf(tmp, 200, "interval: %d\nmin_interv | |
| | | al: %d\npeers:\n", interval, min_interval); | |
| | | s += tmp; | |
| for (std::vector<peer_entry>::const_iterator
i = peers.begin(); | | for (std::vector<peer_entry>::const_iterator
i = peers.begin(); | |
| i != peers.end(); ++i) | | i != peers.end(); ++i) | |
| { | | { | |
|
| s << " " << std::setfill(' ') << st | | char pid[41]; | |
| d::setw(16) << i->ip | | to_hex((const char*)&i->pid[0], 20, | |
| << " " << std::setw(5) << st | | pid); | |
| d::dec << i->port << " "; | | if (i->pid.is_all_zeros()) pid[0] = | |
| if (!i->pid.is_all_zeros()) s << " " | | 0; | |
| << i->pid; | | | |
| s << "\n"; | | snprintf(tmp, 200, " %-16s %-5d %s\n | |
| | | ", i->ip.c_str(), i->port, pid); | |
| | | s += tmp; | |
| } | | } | |
|
| s << "external ip: " << external_ip << "\n"; | | snprintf(tmp, 200, "external ip: %s\n", prin | |
| debug_log(s.str()); | | t_address(external_ip).c_str()); | |
| | | s += tmp; | |
| | | debug_log(s); | |
| } | | } | |
| | | | |
| void tracker_request_timed_out( | | void tracker_request_timed_out( | |
| tracker_request const&) | | tracker_request const&) | |
| { | | { | |
| debug_log("*** tracker timed out"); | | debug_log("*** tracker timed out"); | |
| } | | } | |
| | | | |
| void tracker_request_error( | | void tracker_request_error( | |
| tracker_request const& | | tracker_request const& | |
| , int response_code | | , int response_code | |
|
| , const std::string& str) | | , const std::string& str | |
| | | , int retry_interval) | |
| { | | { | |
|
| debug_log(std::string("*** tracker error: ") | | char msg[256]; | |
| + boost::lexical_cast<std::string>(r | | snprintf(msg, sizeof(msg), "*** tracker erro | |
| esponse_code) + ": " | | r: %d: %s", response_code, str.c_str()); | |
| + str); | | debug_log(msg); | |
| } | | } | |
| | | | |
| void debug_log(const std::string& line) | | void debug_log(const std::string& line) | |
| { | | { | |
| (*m_ses.m_logger) << time_now_string() << "
" << line << "\n"; | | (*m_ses.m_logger) << time_now_string() << "
" << line << "\n"; | |
| } | | } | |
| session_impl& m_ses; | | session_impl& m_ses; | |
| }; | | }; | |
| #endif | | #endif | |
| | | | |
| | | | |
End of changes. 61 change blocks. |
| 61 lines changed or deleted | | 223 lines changed or added | |
|
| session_settings.hpp | | session_settings.hpp | |
| | | | |
| skipping to change at line 92 | | skipping to change at line 92 | |
| { | | { | |
| session_settings(std::string const& user_agent_ = "libtorren
t/" | | session_settings(std::string const& user_agent_ = "libtorren
t/" | |
| LIBTORRENT_VERSION) | | LIBTORRENT_VERSION) | |
| : user_agent(user_agent_) | | : user_agent(user_agent_) | |
| , tracker_completion_timeout(60) | | , tracker_completion_timeout(60) | |
| , tracker_receive_timeout(40) | | , tracker_receive_timeout(40) | |
| , stop_tracker_timeout(5) | | , stop_tracker_timeout(5) | |
| , tracker_maximum_response_length(1024*1024) | | , tracker_maximum_response_length(1024*1024) | |
| , piece_timeout(20) | | , piece_timeout(20) | |
| , request_timeout(50) | | , request_timeout(50) | |
|
| , request_queue_time(3.f) | | , request_queue_time(3) | |
| , max_allowed_in_request_queue(250) | | , max_allowed_in_request_queue(250) | |
| , max_out_request_queue(200) | | , max_out_request_queue(200) | |
| , whole_pieces_threshold(20) | | , whole_pieces_threshold(20) | |
| , peer_timeout(120) | | , peer_timeout(120) | |
| , urlseed_timeout(20) | | , urlseed_timeout(20) | |
| , urlseed_pipeline_size(5) | | , urlseed_pipeline_size(5) | |
| , urlseed_wait_retry(30) | | , urlseed_wait_retry(30) | |
| , file_pool_size(40) | | , file_pool_size(40) | |
| , allow_multiple_connections_per_ip(false) | | , allow_multiple_connections_per_ip(false) | |
| , max_failcount(3) | | , max_failcount(3) | |
| , min_reconnect_time(60) | | , min_reconnect_time(60) | |
| , peer_connect_timeout(7) | | , peer_connect_timeout(7) | |
| , ignore_limits_on_local_network(true) | | , ignore_limits_on_local_network(true) | |
| , connection_speed(10) | | , connection_speed(10) | |
| , send_redundant_have(false) | | , send_redundant_have(false) | |
| , lazy_bitfields(true) | | , lazy_bitfields(true) | |
| , inactivity_timeout(600) | | , inactivity_timeout(600) | |
| , unchoke_interval(15) | | , unchoke_interval(15) | |
|
| , optimistic_unchoke_multiplier(4) | | , optimistic_unchoke_interval(30) | |
| , num_want(200) | | , num_want(200) | |
| , initial_picker_threshold(4) | | , initial_picker_threshold(4) | |
| , allowed_fast_set_size(10) | | , allowed_fast_set_size(10) | |
|
| , max_outstanding_disk_bytes_per_connection(64 * 102
4) | | , max_queued_disk_bytes(256 * 1024) | |
| , handshake_timeout(10) | | , handshake_timeout(10) | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| , use_dht_as_fallback(false) | | , use_dht_as_fallback(false) | |
| #endif | | #endif | |
| , free_torrent_hashes(true) | | , free_torrent_hashes(true) | |
| , upnp_ignore_nonrouters(false) | | , upnp_ignore_nonrouters(false) | |
|
| , send_buffer_watermark(80 * 1024) | | , send_buffer_watermark(100 * 1024) | |
| , auto_upload_slots(true) | | , auto_upload_slots(true) | |
|
| | | , auto_upload_slots_rate_based(true) | |
| , use_parole_mode(true) | | , use_parole_mode(true) | |
|
| , cache_size(512) | | , cache_size(1024) | |
| | | , cache_buffer_chunk_size(16) | |
| , cache_expiry(60) | | , cache_expiry(60) | |
|
| | | , use_read_cache(true) | |
| | | , disk_io_write_mode(0) | |
| | | , disk_io_read_mode(0) | |
| | | , coalesce_reads(false) | |
| | | , coalesce_writes(false) | |
| , outgoing_ports(0,0) | | , outgoing_ports(0,0) | |
| , peer_tos(0) | | , peer_tos(0) | |
| , active_downloads(8) | | , active_downloads(8) | |
| , active_seeds(5) | | , active_seeds(5) | |
| , active_limit(15) | | , active_limit(15) | |
|
| | | , auto_manage_prefer_seeds(false) | |
| , dont_count_slow_torrents(true) | | , dont_count_slow_torrents(true) | |
| , auto_manage_interval(30) | | , auto_manage_interval(30) | |
| , share_ratio_limit(2.f) | | , share_ratio_limit(2.f) | |
| , seed_time_ratio_limit(7.f) | | , seed_time_ratio_limit(7.f) | |
| , seed_time_limit(24 * 60 * 60) // 24 hours | | , seed_time_limit(24 * 60 * 60) // 24 hours | |
| , peer_turnover(1 / 100.f) | | , peer_turnover(1 / 100.f) | |
| , peer_turnover_cutoff(1.1f) // disable until the cr
ash is resolved | | , peer_turnover_cutoff(1.1f) // disable until the cr
ash is resolved | |
| , close_redundant_connections(true) | | , close_redundant_connections(true) | |
| , auto_scrape_interval(1800) | | , auto_scrape_interval(1800) | |
| , auto_scrape_min_interval(300) | | , auto_scrape_min_interval(300) | |
|
| , max_peerlist_size(8000) | | , max_peerlist_size(4000) | |
| | | , max_paused_peerlist_size(4000) | |
| , min_announce_interval(5 * 60) | | , min_announce_interval(5 * 60) | |
| , prioritize_partial_pieces(false) | | , prioritize_partial_pieces(false) | |
| , auto_manage_startup(120) | | , auto_manage_startup(120) | |
| , rate_limit_ip_overhead(true) | | , rate_limit_ip_overhead(true) | |
|
| | | , announce_to_all_trackers(false) | |
| | | , announce_to_all_tiers(false) | |
| | | , prefer_udp_trackers(true) | |
| | | , strict_super_seeding(false) | |
| | | , seeding_piece_quota(3) | |
| | | #ifdef TORRENT_WINDOWS | |
| | | , max_sparse_regions(30000) | |
| | | #else | |
| | | , max_sparse_regions(0) | |
| | | #endif | |
| | | #ifndef TORRENT_DISABLE_MLOCK | |
| | | , lock_disk_cache(true) | |
| | | #endif | |
| | | , max_rejects(50) | |
| | | , recv_socket_buffer_size(0) | |
| | | , send_socket_buffer_size(0) | |
| | | , optimize_hashing_for_speed(true) | |
| | | , file_checks_delay_per_block(0) | |
| | | , disk_cache_algorithm(largest_contiguous) | |
| | | , read_cache_line_size(16) | |
| | | , write_cache_line_size(32) | |
| | | , optimistic_disk_retry(10 * 60) | |
| | | , disable_hash_checks(false) | |
| | | , allow_reordered_disk_operations(true) | |
| | | , max_suggest_pieces(10) | |
| | | , drop_skipped_requests(false) | |
| | | , low_prio_disk(true) | |
| | | , local_service_announce_interval(5 * 60) | |
| | | , udp_tracker_token_expiry(60) | |
| | | , report_true_downloaded(false) | |
| | | , strict_end_game_mode(true) | |
| {} | | {} | |
| | | | |
| // this is the user agent that will be sent to the tracker | | // this is the user agent that will be sent to the tracker | |
| // when doing requests. It is used to identify the client. | | // when doing requests. It is used to identify the client. | |
| // It cannot contain \r or \n | | // It cannot contain \r or \n | |
| std::string user_agent; | | std::string user_agent; | |
| | | | |
| // the number of seconds to wait until giving up on a | | // the number of seconds to wait until giving up on a | |
| // tracker request if it hasn't finished | | // tracker request if it hasn't finished | |
| int tracker_completion_timeout; | | int tracker_completion_timeout; | |
| | | | |
| skipping to change at line 186 | | skipping to change at line 226 | |
| | | | |
| // the number of seconds one block (16kB) is expected | | // the number of seconds one block (16kB) is expected | |
| // to be received within. If it's not, the block is | | // to be received within. If it's not, the block is | |
| // requested from a different peer | | // requested from a different peer | |
| int request_timeout; | | int request_timeout; | |
| | | | |
| // the length of the request queue given in the number | | // the length of the request queue given in the number | |
| // of seconds it should take for the other end to send | | // of seconds it should take for the other end to send | |
| // all the pieces. i.e. the actual number of requests | | // all the pieces. i.e. the actual number of requests | |
| // depends on the download rate and this number. | | // depends on the download rate and this number. | |
|
| float request_queue_time; | | int request_queue_time; | |
| | | | |
| // the number of outstanding block requests a peer is | | // the number of outstanding block requests a peer is | |
| // allowed to queue up in the client. If a peer sends | | // allowed to queue up in the client. If a peer sends | |
| // more requests than this (before the first one has | | // more requests than this (before the first one has | |
| // been sent) the last request will be dropped. | | // been sent) the last request will be dropped. | |
| // the higher this is, the faster upload speeds the | | // the higher this is, the faster upload speeds the | |
| // client can get to a single peer. | | // client can get to a single peer. | |
| int max_allowed_in_request_queue; | | int max_allowed_in_request_queue; | |
| | | | |
| // the maximum number of outstanding requests to | | // the maximum number of outstanding requests to | |
| | | | |
| skipping to change at line 284 | | skipping to change at line 324 | |
| bool lazy_bitfields; | | bool lazy_bitfields; | |
| | | | |
| // if a peer is uninteresting and uninterested for longer | | // if a peer is uninteresting and uninterested for longer | |
| // than this number of seconds, it will be disconnected. | | // than this number of seconds, it will be disconnected. | |
| // default is 10 minutes | | // default is 10 minutes | |
| int inactivity_timeout; | | int inactivity_timeout; | |
| | | | |
| // the number of seconds between chokes/unchokes | | // the number of seconds between chokes/unchokes | |
| int unchoke_interval; | | int unchoke_interval; | |
| | | | |
|
| // the number of unchoke intervals between | | // the number of seconds between | |
| // optimistic unchokes | | // optimistic unchokes | |
|
| int optimistic_unchoke_multiplier; | | int optimistic_unchoke_interval; | |
| | | | |
| // if this is set, this IP will be reported do the | | // if this is set, this IP will be reported do the | |
| // tracker in the ip= parameter. | | // tracker in the ip= parameter. | |
| address announce_ip; | | address announce_ip; | |
| | | | |
| // the num want sent to trackers | | // the num want sent to trackers | |
| int num_want; | | int num_want; | |
| | | | |
| // while we have fewer pieces than this, pick | | // while we have fewer pieces than this, pick | |
| // random pieces instead of rarest first. | | // random pieces instead of rarest first. | |
| int initial_picker_threshold; | | int initial_picker_threshold; | |
| | | | |
| // the number of allowed pieces to send to peers | | // the number of allowed pieces to send to peers | |
| // that supports the fast extensions | | // that supports the fast extensions | |
| int allowed_fast_set_size; | | int allowed_fast_set_size; | |
| | | | |
| // the maximum number of bytes a connection may have | | // the maximum number of bytes a connection may have | |
| // pending in the disk write queue before its download | | // pending in the disk write queue before its download | |
| // rate is being throttled. This prevents fast downloads | | // rate is being throttled. This prevents fast downloads | |
| // to slow medias to allocate more and more memory | | // to slow medias to allocate more and more memory | |
|
| // indefinitely. This should be set to at least 32 kB | | // indefinitely. This should be set to at least 16 kB | |
| // to not completely disrupt normal downloads. | | // to not completely disrupt normal downloads. If it's | |
| int max_outstanding_disk_bytes_per_connection; | | // set to 0, you will be starving the disk thread and | |
| | | // nothing will be written to disk. | |
| | | // this is a per session setting. | |
| | | int max_queued_disk_bytes; | |
| | | | |
| // the number of seconds to wait for a handshake | | // the number of seconds to wait for a handshake | |
| // response from a peer. If no response is received | | // response from a peer. If no response is received | |
| // within this time, the peer is disconnected. | | // within this time, the peer is disconnected. | |
| int handshake_timeout; | | int handshake_timeout; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
|
| // while this is true, the dht will note be used unless the | | // while this is true, the dht will not be used unless the | |
| // tracker is online | | // tracker is online | |
| bool use_dht_as_fallback; | | bool use_dht_as_fallback; | |
| #endif | | #endif | |
| | | | |
| // if this is true, the piece hashes will be freed, in order | | // if this is true, the piece hashes will be freed, in order | |
| // to save memory, once the torrent is seeding. This will | | // to save memory, once the torrent is seeding. This will | |
| // make the get_torrent_info() function to return an incompl
ete | | // make the get_torrent_info() function to return an incompl
ete | |
| // torrent object that cannot be passed back to add_torrent(
) | | // torrent object that cannot be passed back to add_torrent(
) | |
| bool free_torrent_hashes; | | bool free_torrent_hashes; | |
| | | | |
| | | | |
| skipping to change at line 350 | | skipping to change at line 393 | |
| | | | |
| // if auto_upload_slots is true, and a global upload | | // if auto_upload_slots is true, and a global upload | |
| // limit is set and the upload rate is less than 90% | | // limit is set and the upload rate is less than 90% | |
| // of the upload limit, on new slot is opened up. If | | // of the upload limit, on new slot is opened up. If | |
| // the upload rate is >= upload limit for an extended | | // the upload rate is >= upload limit for an extended | |
| // period of time, one upload slot is closed. The | | // period of time, one upload slot is closed. The | |
| // upload slots are never automatically decreased below | | // upload slots are never automatically decreased below | |
| // the manual settings, through max_uploads. | | // the manual settings, through max_uploads. | |
| bool auto_upload_slots; | | bool auto_upload_slots; | |
| | | | |
|
| | | // this only affects the auto upload slots mechanism. | |
| | | // if auto_upload_slots is false, this field is not | |
| | | // considered. | |
| | | bool auto_upload_slots_rate_based; | |
| | | | |
| // if set to true, peers that participate in a failing | | // if set to true, peers that participate in a failing | |
| // piece is put in parole mode. i.e. They will only | | // piece is put in parole mode. i.e. They will only | |
| // download whole pieces until they either fail or pass. | | // download whole pieces until they either fail or pass. | |
| // they are taken out of parole mode as soon as they | | // they are taken out of parole mode as soon as they | |
| // participate in a piece that passes. | | // participate in a piece that passes. | |
| bool use_parole_mode; | | bool use_parole_mode; | |
| | | | |
| // the disk write cache, specified in 16 KiB blocks. | | // the disk write cache, specified in 16 KiB blocks. | |
|
| // default is 512 (= 8 MB) | | // default is 1024 (= 16 MiB). -1 means automatic, which | |
| | | // adjusts the cache size depending on the amount | |
| | | // of physical RAM in the machine. | |
| int cache_size; | | int cache_size; | |
| | | | |
|
| | | // this is the number of disk buffer blocks (16 kiB) | |
| | | // that should be allocated at a time. It must be | |
| | | // at least 1. Lower number saves memory at the expense | |
| | | // of more heap allocations | |
| | | int cache_buffer_chunk_size; | |
| | | | |
| // the number of seconds a write cache entry sits | | // the number of seconds a write cache entry sits | |
| // idle in the cache before it's forcefully flushed | | // idle in the cache before it's forcefully flushed | |
| // to disk. Default is 60 seconds. | | // to disk. Default is 60 seconds. | |
| int cache_expiry; | | int cache_expiry; | |
| | | | |
|
| | | // when true, the disk I/O thread uses the disk | |
| | | // cache for caching blocks read from disk too | |
| | | bool use_read_cache; | |
| | | | |
| | | enum io_buffer_mode_t | |
| | | { | |
| | | enable_os_cache = 0, | |
| | | disable_os_cache_for_aligned_files = 1, | |
| | | disable_os_cache = 2 | |
| | | }; | |
| | | int disk_io_write_mode; | |
| | | int disk_io_read_mode; | |
| | | | |
| | | bool coalesce_reads; | |
| | | bool coalesce_writes; | |
| | | | |
| // if != (0, 0), this is the range of ports that | | // if != (0, 0), this is the range of ports that | |
| // outgoing connections will be bound to. This | | // outgoing connections will be bound to. This | |
| // is useful for users that have routers that | | // is useful for users that have routers that | |
| // allow QoS settings based on local port. | | // allow QoS settings based on local port. | |
| std::pair<int, int> outgoing_ports; | | std::pair<int, int> outgoing_ports; | |
| | | | |
| // the TOS byte of all peer traffic (including | | // the TOS byte of all peer traffic (including | |
| // web seeds) is set to this value. The default | | // web seeds) is set to this value. The default | |
| // is the QBSS scavenger service | | // is the QBSS scavenger service | |
| // http://qbone.internet2.edu/qbss/ | | // http://qbone.internet2.edu/qbss/ | |
| | | | |
| skipping to change at line 387 | | skipping to change at line 459 | |
| char peer_tos; | | char peer_tos; | |
| | | | |
| // for auto managed torrents, these are the limits | | // for auto managed torrents, these are the limits | |
| // they are subject to. If there are too many torrents | | // they are subject to. If there are too many torrents | |
| // some of the auto managed ones will be paused until | | // some of the auto managed ones will be paused until | |
| // some slots free up. | | // some slots free up. | |
| int active_downloads; | | int active_downloads; | |
| int active_seeds; | | int active_seeds; | |
| int active_limit; | | int active_limit; | |
| | | | |
|
| | | // prefer seeding torrents when determining which torrents t | |
| | | o give | |
| | | // active slots to, the default is false which gives prefere | |
| | | nce to | |
| | | // downloading torrents | |
| | | bool auto_manage_prefer_seeds; | |
| | | | |
| // if this is true, torrents that don't have any significant | | // if this is true, torrents that don't have any significant | |
| // transfers are not counted as active when determining whic
h | | // transfers are not counted as active when determining whic
h | |
| // auto managed torrents to pause and resume | | // auto managed torrents to pause and resume | |
| bool dont_count_slow_torrents; | | bool dont_count_slow_torrents; | |
| | | | |
| // the number of seconds in between recalculating which | | // the number of seconds in between recalculating which | |
| // torrents to activate and which ones to queue | | // torrents to activate and which ones to queue | |
| int auto_manage_interval; | | int auto_manage_interval; | |
| | | | |
| // when a seeding torrent reaches eaither the share ratio | | // when a seeding torrent reaches eaither the share ratio | |
| | | | |
| skipping to change at line 414 | | skipping to change at line 491 | |
| float share_ratio_limit; | | float share_ratio_limit; | |
| float seed_time_ratio_limit; | | float seed_time_ratio_limit; | |
| int seed_time_limit; | | int seed_time_limit; | |
| | | | |
| // the percentage of peers to disconnect every | | // the percentage of peers to disconnect every | |
| // 90 seconds (if we're at the peer limit) | | // 90 seconds (if we're at the peer limit) | |
| // defaults to 1/50:th | | // defaults to 1/50:th | |
| float peer_turnover; | | float peer_turnover; | |
| | | | |
| // when we are connected to more than | | // when we are connected to more than | |
|
| // limit * peer_turnover_enable peers | | // limit * peer_turnover_cutoff peers | |
| // disconnect peer_turnover fraction | | // disconnect peer_turnover fraction | |
| // of the peers | | // of the peers | |
| float peer_turnover_cutoff; | | float peer_turnover_cutoff; | |
| | | | |
| // if this is true (default) connections where both | | // if this is true (default) connections where both | |
| // ends have no utility in keeping the connection open | | // ends have no utility in keeping the connection open | |
| // are closed. for instance if both ends have completed | | // are closed. for instance if both ends have completed | |
| // their downloads | | // their downloads | |
| bool close_redundant_connections; | | bool close_redundant_connections; | |
| | | | |
| | | | |
| skipping to change at line 438 | | skipping to change at line 515 | |
| | | | |
| // the minimum number of seconds between any | | // the minimum number of seconds between any | |
| // automatic scrape (regardless of torrent) | | // automatic scrape (regardless of torrent) | |
| int auto_scrape_min_interval; | | int auto_scrape_min_interval; | |
| | | | |
| // the max number of peers in the peer list | | // the max number of peers in the peer list | |
| // per torrent. This is the peers we know | | // per torrent. This is the peers we know | |
| // about, not necessarily connected to. | | // about, not necessarily connected to. | |
| int max_peerlist_size; | | int max_peerlist_size; | |
| | | | |
|
| | | // when a torrent is paused, this is the max peer | |
| | | // list size that's used | |
| | | int max_paused_peerlist_size; | |
| | | | |
| // any announce intervals reported from a tracker | | // any announce intervals reported from a tracker | |
| // that is lower than this, will be clamped to this | | // that is lower than this, will be clamped to this | |
| // value. It's specified in seconds | | // value. It's specified in seconds | |
| int min_announce_interval; | | int min_announce_interval; | |
| | | | |
| // if true, partial pieces are picked before pieces | | // if true, partial pieces are picked before pieces | |
| // that are more rare | | // that are more rare | |
| bool prioritize_partial_pieces; | | bool prioritize_partial_pieces; | |
| | | | |
| // the number of seconds a torrent is considered | | // the number of seconds a torrent is considered | |
| | | | |
| skipping to change at line 459 | | skipping to change at line 540 | |
| // upload and download speed. This is so that | | // upload and download speed. This is so that | |
| // newly started torrents are not considered | | // newly started torrents are not considered | |
| // inactive until they have a fair chance to | | // inactive until they have a fair chance to | |
| // start downloading. | | // start downloading. | |
| int auto_manage_startup; | | int auto_manage_startup; | |
| | | | |
| // if set to true, the estimated TCP/IP overhead is | | // if set to true, the estimated TCP/IP overhead is | |
| // drained from the rate limiters, to avoid exceeding | | // drained from the rate limiters, to avoid exceeding | |
| // the limits with the total traffic | | // the limits with the total traffic | |
| bool rate_limit_ip_overhead; | | bool rate_limit_ip_overhead; | |
|
| | | | |
| | | // this announces to all trackers within the current | |
| | | // tier. Trackers within a tier are supposed to share | |
| | | // peers, this could be used for trackers that don't, | |
| | | // and require the clients to announce to all of them. | |
| | | bool announce_to_all_trackers; | |
| | | | |
| | | // if set to true, multi tracker torrents are treated | |
| | | // the same way uTorrent treats them. It defaults to | |
| | | // false in order to comply with the extension definition. | |
| | | // When this is enabled, one tracker from each tier is | |
| | | // announced | |
| | | bool announce_to_all_tiers; | |
| | | | |
| | | // when this is set to true, if there is a tracker entry | |
| | | // with udp:// protocol, it is preferred over the same | |
| | | // tracker over http://. | |
| | | bool prefer_udp_trackers; | |
| | | | |
| | | // when set to true, a piece has to have been forwarded | |
| | | // to a third peer before another one is handed out | |
| | | bool strict_super_seeding; | |
| | | | |
| | | // the number of pieces to send to each peer when seeding | |
| | | // before rotating to a new peer | |
| | | int seeding_piece_quota; | |
| | | | |
| | | // the maximum number of sparse regions before starting | |
| | | // to prioritize pieces close to other pieces (to maintain | |
| | | // the number of sparse regions). This is set to 30000 on | |
| | | // windows because windows vista has a new limit on the | |
| | | // numbers of sparse regions one file may have | |
| | | // if it is set to 0 this behavior is disabled | |
| | | // this is a hack to avoid a terrible bug on windows | |
| | | // don't use unless you have to, it screws with rarest-first | |
| | | // piece selection, and reduces swarm performance | |
| | | int max_sparse_regions; | |
| | | | |
| | | #ifndef TORRENT_DISABLE_MLOCK | |
| | | // if this is set to true, the memory allocated for the | |
| | | // disk cache will be locked in physical RAM, never to | |
| | | // be swapped out | |
| | | bool lock_disk_cache; | |
| | | #endif | |
| | | | |
| | | // the number of times to reject requests while being | |
| | | // choked before disconnecting a peer for being malicious | |
| | | int max_rejects; | |
| | | | |
| | | // sets the socket send and receive buffer sizes | |
| | | // 0 means OS default | |
| | | int recv_socket_buffer_size; | |
| | | int send_socket_buffer_size; | |
| | | | |
| | | // if this is set to false, the hashing will be | |
| | | // optimized for memory usage instead of the | |
| | | // number of read operations | |
| | | bool optimize_hashing_for_speed; | |
| | | | |
| | | // if > 0, file checks will have a short | |
| | | // delay between disk operations, to make it | |
| | | // less intrusive on the system as a whole | |
| | | // blocking the disk. This delay is specified | |
| | | // in milliseconds and the delay will be this | |
| | | // long per 16kiB block | |
| | | // the default of 10 ms/16kiB will limit | |
| | | // the checking rate to 1.6 MiB per second | |
| | | int file_checks_delay_per_block; | |
| | | | |
| | | enum disk_cache_algo_t | |
| | | { lru, largest_contiguous }; | |
| | | | |
| | | disk_cache_algo_t disk_cache_algorithm; | |
| | | | |
| | | // the number of blocks that will be read ahead | |
| | | // when reading a block into the read cache | |
| | | int read_cache_line_size; | |
| | | | |
| | | // whenever a contiguous range of this many | |
| | | // blocks is found in the write cache, it | |
| | | // is flushed immediately | |
| | | int write_cache_line_size; | |
| | | | |
| | | // this is the number of seconds a disk failure | |
| | | // occurs until libtorrent will re-try. | |
| | | int optimistic_disk_retry; | |
| | | | |
| | | // when set to true, all data downloaded from | |
| | | // peers will be assumed to be correct, and not | |
| | | // tested to match the hashes in the torrent | |
| | | // this is only useful for simulation and | |
| | | // testing purposes (typically combined with | |
| | | // disabled_storage) | |
| | | bool disable_hash_checks; | |
| | | | |
| | | // if this is true, disk read operations may | |
| | | // be re-ordered based on their physical disk | |
| | | // read offset. This greatly improves throughput | |
| | | // when uploading to many peers. This assumes | |
| | | // a traditional hard drive with a read head | |
| | | // and spinning platters. If your storage medium | |
| | | // is a solid state drive, this optimization | |
| | | // doesn't give you an benefits | |
| | | bool allow_reordered_disk_operations; | |
| | | | |
| | | // the max number of pieces that a peer can | |
| | | // suggest to use before we start dropping | |
| | | // previous suggested piece | |
| | | int max_suggest_pieces; | |
| | | | |
| | | // if set to true, requests that have have not been | |
| | | // satisfied after the equivalence of the entire | |
| | | // request queue has been received, will be considered lost | |
| | | bool drop_skipped_requests; | |
| | | | |
| | | // if this is set to true, the disk I/O will be | |
| | | // run at lower-than-normal priority. This is | |
| | | // intended to make the machine more responsive | |
| | | // to foreground tasks, while bittorrent runs | |
| | | // in the background | |
| | | bool low_prio_disk; | |
| | | | |
| | | // number of seconds between local service announces for | |
| | | // torrents. Defaults to 5 minutes | |
| | | int local_service_announce_interval; | |
| | | | |
| | | // the number of seconds a connection ID received | |
| | | // from a UDP tracker is valid for. This is specified | |
| | | // as 60 seconds | |
| | | int udp_tracker_token_expiry; | |
| | | | |
| | | // when set to true, the downloaded counter sent to trackers | |
| | | // will include the actual number of payload bytes donwnload | |
| | | ed | |
| | | // including redundant bytes. If set to false, it will not i | |
| | | nclude | |
| | | // any redundany bytes | |
| | | bool report_true_downloaded; | |
| | | | |
| | | // if set to true, libtorrent won't request a piece multiple | |
| | | times | |
| | | // until every piece is requested | |
| | | bool strict_end_game_mode; | |
| }; | | }; | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| struct dht_settings | | struct dht_settings | |
| { | | { | |
| dht_settings() | | dht_settings() | |
| : max_peers_reply(100) | | : max_peers_reply(100) | |
| , search_branching(5) | | , search_branching(5) | |
| , service_port(0) | | , service_port(0) | |
| , max_fail_count(20) | | , max_fail_count(20) | |
| | | | |
End of changes. 23 change blocks. |
| 15 lines changed or deleted | | 241 lines changed or added | |
|
| stat.hpp | | stat.hpp | |
| | | | |
| skipping to change at line 64 | | skipping to change at line 64 | |
| stat_channel() | | stat_channel() | |
| : m_counter(0) | | : m_counter(0) | |
| , m_total_counter(0) | | , m_total_counter(0) | |
| , m_rate_sum(0) | | , m_rate_sum(0) | |
| { | | { | |
| std::memset(m_rate_history, 0, sizeof(m_rate_history
)); | | std::memset(m_rate_history, 0, sizeof(m_rate_history
)); | |
| } | | } | |
| | | | |
| void operator+=(stat_channel const& s) | | void operator+=(stat_channel const& s) | |
| { | | { | |
|
| | | TORRENT_ASSERT(m_counter >= 0); | |
| | | TORRENT_ASSERT(m_total_counter >= 0); | |
| | | TORRENT_ASSERT(s.m_counter >= 0); | |
| m_counter += s.m_counter; | | m_counter += s.m_counter; | |
| m_total_counter += s.m_counter; | | m_total_counter += s.m_counter; | |
|
| | | TORRENT_ASSERT(m_counter >= 0); | |
| | | TORRENT_ASSERT(m_total_counter >= 0); | |
| } | | } | |
| | | | |
| void add(int count) | | void add(int count) | |
| { | | { | |
| TORRENT_ASSERT(count >= 0); | | TORRENT_ASSERT(count >= 0); | |
| | | | |
| m_counter += count; | | m_counter += count; | |
|
| | | TORRENT_ASSERT(m_counter >= 0); | |
| m_total_counter += count; | | m_total_counter += count; | |
|
| | | TORRENT_ASSERT(m_total_counter >= 0); | |
| } | | } | |
| | | | |
| // should be called once every second | | // should be called once every second | |
|
| void second_tick(float tick_interval); | | void second_tick(int tick_interval_ms); | |
| float rate() const { return m_rate_sum / float(history); } | | int rate() const { return m_rate_sum / history; } | |
| size_type rate_sum() const { return m_rate_sum; } | | size_type rate_sum() const { return m_rate_sum; } | |
| size_type total() const { return m_total_counter; } | | size_type total() const { return m_total_counter; } | |
| | | | |
|
| void offset(size_type counter) | | void offset(size_type c) | |
| { | | { | |
|
| TORRENT_ASSERT(counter >= 0); | | TORRENT_ASSERT(c >= 0); | |
| m_total_counter += counter; | | TORRENT_ASSERT(m_total_counter >= 0); | |
| | | m_total_counter += c; | |
| | | TORRENT_ASSERT(m_total_counter >= 0); | |
| } | | } | |
| | | | |
| size_type counter() const { return m_counter; } | | size_type counter() const { return m_counter; } | |
| | | | |
| void clear() | | void clear() | |
| { | | { | |
| std::memset(m_rate_history, 0, sizeof(m_rate_history
)); | | std::memset(m_rate_history, 0, sizeof(m_rate_history
)); | |
| m_counter = 0; | | m_counter = 0; | |
| m_total_counter = 0; | | m_total_counter = 0; | |
| m_rate_sum = 0; | | m_rate_sum = 0; | |
| } | | } | |
| | | | |
| private: | | private: | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const | | void check_invariant() const | |
| { | | { | |
|
| int sum = 0; | | size_type sum = 0; | |
| for (int i = 0; i < history; ++i) sum += m_rate_hist
ory[i]; | | for (int i = 0; i < history; ++i) sum += m_rate_hist
ory[i]; | |
| TORRENT_ASSERT(m_rate_sum == sum); | | TORRENT_ASSERT(m_rate_sum == sum); | |
| TORRENT_ASSERT(m_total_counter >= 0); | | TORRENT_ASSERT(m_total_counter >= 0); | |
| } | | } | |
| #endif | | #endif | |
| | | | |
| // history of rates a few seconds back | | // history of rates a few seconds back | |
| int m_rate_history[history]; | | int m_rate_history[history]; | |
| | | | |
| // the accumulator for this second. | | // the accumulator for this second. | |
| | | | |
| skipping to change at line 133 | | skipping to change at line 142 | |
| class TORRENT_EXPORT stat | | class TORRENT_EXPORT stat | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| public: | | public: | |
| void operator+=(const stat& s) | | void operator+=(const stat& s) | |
| { | | { | |
| for (int i = 0; i < num_channels; ++i) | | for (int i = 0; i < num_channels; ++i) | |
| m_stat[i] += s.m_stat[i]; | | m_stat[i] += s.m_stat[i]; | |
| } | | } | |
| | | | |
|
| | | void sent_syn(bool ipv6) | |
| | | { | |
| | | m_stat[upload_ip_protocol].add(ipv6 ? 60 : 40); | |
| | | } | |
| | | | |
| | | void received_synack(bool ipv6) | |
| | | { | |
| | | // we received SYN-ACK and also sent ACK back | |
| | | m_stat[download_ip_protocol].add(ipv6 ? 60 : 40); | |
| | | m_stat[upload_ip_protocol].add(ipv6 ? 60 : 40); | |
| | | } | |
| | | | |
| | | void received_dht_bytes(int bytes) | |
| | | { | |
| | | TORRENT_ASSERT(bytes >= 0); | |
| | | m_stat[download_dht_protocol].add(bytes); | |
| | | } | |
| | | | |
| | | void sent_dht_bytes(int bytes) | |
| | | { | |
| | | TORRENT_ASSERT(bytes >= 0); | |
| | | m_stat[upload_dht_protocol].add(bytes); | |
| | | } | |
| | | | |
| | | void received_tracker_bytes(int bytes) | |
| | | { | |
| | | TORRENT_ASSERT(bytes >= 0); | |
| | | m_stat[download_tracker_protocol].add(bytes); | |
| | | } | |
| | | | |
| | | void sent_tracker_bytes(int bytes) | |
| | | { | |
| | | TORRENT_ASSERT(bytes >= 0); | |
| | | m_stat[upload_tracker_protocol].add(bytes); | |
| | | } | |
| | | | |
| void received_bytes(int bytes_payload, int bytes_protocol) | | void received_bytes(int bytes_payload, int bytes_protocol) | |
| { | | { | |
| TORRENT_ASSERT(bytes_payload >= 0); | | TORRENT_ASSERT(bytes_payload >= 0); | |
| TORRENT_ASSERT(bytes_protocol >= 0); | | TORRENT_ASSERT(bytes_protocol >= 0); | |
| | | | |
| m_stat[download_payload].add(bytes_payload); | | m_stat[download_payload].add(bytes_payload); | |
| m_stat[download_protocol].add(bytes_protocol); | | m_stat[download_protocol].add(bytes_protocol); | |
| } | | } | |
| | | | |
| void sent_bytes(int bytes_payload, int bytes_protocol) | | void sent_bytes(int bytes_payload, int bytes_protocol) | |
| { | | { | |
| TORRENT_ASSERT(bytes_payload >= 0); | | TORRENT_ASSERT(bytes_payload >= 0); | |
| TORRENT_ASSERT(bytes_protocol >= 0); | | TORRENT_ASSERT(bytes_protocol >= 0); | |
| | | | |
| m_stat[upload_payload].add(bytes_payload); | | m_stat[upload_payload].add(bytes_payload); | |
| m_stat[upload_protocol].add(bytes_protocol); | | m_stat[upload_protocol].add(bytes_protocol); | |
| } | | } | |
| | | | |
|
| // calculate ip protocol overhead | | // and IP packet was received or sent | |
| void calc_ip_overhead() | | // account for the overhead caused by it | |
| | | void trancieve_ip_packet(int bytes_transferred, bool ipv6) | |
| { | | { | |
|
| int uploaded = m_stat[upload_protocol].counter() | | // one TCP/IP packet header for the packet | |
| + m_stat[upload_payload].counter(); | | // sent or received, and one for the ACK | |
| int downloaded = m_stat[download_protocol].counter() | | // The IPv4 header is 20 bytes | |
| + m_stat[download_payload].counter(); | | // and IPv6 header is 40 bytes | |
| | | const int header = (ipv6 ? 40 : 20) + 20; | |
| // IP + TCP headers are 40 bytes per MTU (1460) | | const int mtu = 1500; | |
| // bytes of payload, but at least 40 bytes | | const int packet_size = mtu - header; | |
| m_stat[upload_ip_protocol].add((std::max)(uploaded / | | const int overhead = (std::max)(1, (bytes_transferre | |
| 1460, uploaded>0?40:0)); | | d + packet_size - 1) / packet_size) * header; | |
| m_stat[download_ip_protocol].add((std::max)(download | | m_stat[download_ip_protocol].add(overhead); | |
| ed / 1460, downloaded>0?40:0)); | | m_stat[upload_ip_protocol].add(overhead); | |
| | | | |
| // also account for ACK traffic. That adds to the tr | | | |
| ansfers | | | |
| // in the opposite direction. Even on connections wi | | | |
| th symmetric | | | |
| // transfer rates, it seems to add a penalty. | | | |
| m_stat[upload_ip_protocol].add((std::max)(downloaded | | | |
| * 40 / 1460, downloaded>0?40:0)); | | | |
| m_stat[download_ip_protocol].add((std::max)(uploaded | | | |
| * 40 / 1460, uploaded>0?40:0)); | | | |
| } | | } | |
| | | | |
| int upload_ip_overhead() const { return m_stat[upload_ip_pro
tocol].counter(); } | | int upload_ip_overhead() const { return m_stat[upload_ip_pro
tocol].counter(); } | |
| int download_ip_overhead() const { return m_stat[download_ip
_protocol].counter(); } | | int download_ip_overhead() const { return m_stat[download_ip
_protocol].counter(); } | |
|
| | | int upload_dht() const { return m_stat[upload_dht_protocol]. | |
| | | counter(); } | |
| | | int download_dht() const { return m_stat[download_dht_protoc | |
| | | ol].counter(); } | |
| | | int download_tracker() const { return m_stat[download_tracke | |
| | | r_protocol].counter(); } | |
| | | int upload_tracker() const { return m_stat[upload_tracker_pr | |
| | | otocol].counter(); } | |
| | | | |
| // should be called once every second | | // should be called once every second | |
|
| void second_tick(float tick_interval) | | void second_tick(int tick_interval_ms) | |
| { | | { | |
| for (int i = 0; i < num_channels; ++i) | | for (int i = 0; i < num_channels; ++i) | |
|
| m_stat[i].second_tick(tick_interval); | | m_stat[i].second_tick(tick_interval_ms); | |
| } | | } | |
| | | | |
|
| float upload_rate() const | | int upload_rate() const | |
| { | | { | |
| return (m_stat[upload_payload].rate_sum() | | return (m_stat[upload_payload].rate_sum() | |
| + m_stat[upload_protocol].rate_sum() | | + m_stat[upload_protocol].rate_sum() | |
|
| + m_stat[upload_ip_protocol].rate_sum()) | | + m_stat[upload_ip_protocol].rate_sum() | |
| / float(stat_channel::history); | | + m_stat[upload_dht_protocol].rate_sum()) | |
| | | / stat_channel::history; | |
| } | | } | |
| | | | |
|
| float download_rate() const | | int download_rate() const | |
| { | | { | |
| return (m_stat[download_payload].rate_sum() | | return (m_stat[download_payload].rate_sum() | |
| + m_stat[download_protocol].rate_sum() | | + m_stat[download_protocol].rate_sum() | |
|
| + m_stat[download_ip_protocol].rate_sum()) | | + m_stat[download_ip_protocol].rate_sum() | |
| / float(stat_channel::history); | | + m_stat[download_dht_protocol].rate_sum()) | |
| | | / stat_channel::history; | |
| } | | } | |
| | | | |
|
| float upload_payload_rate() const | | size_type total_upload() const | |
| { return m_stat[upload_payload].rate(); } | | { | |
| | | return m_stat[upload_payload].total() | |
| | | + m_stat[upload_protocol].total() | |
| | | + m_stat[upload_ip_protocol].total() | |
| | | + m_stat[upload_dht_protocol].total() | |
| | | + m_stat[upload_tracker_protocol].total(); | |
| | | } | |
| | | | |
|
| float download_payload_rate() const | | size_type total_download() const | |
| | | { | |
| | | return m_stat[download_payload].total() | |
| | | + m_stat[download_protocol].total() | |
| | | + m_stat[download_ip_protocol].total() | |
| | | + m_stat[download_dht_protocol].total() | |
| | | + m_stat[download_tracker_protocol].total(); | |
| | | } | |
| | | | |
| | | int upload_payload_rate() const | |
| | | { return m_stat[upload_payload].rate(); } | |
| | | int download_payload_rate() const | |
| { return m_stat[download_payload].rate(); } | | { return m_stat[download_payload].rate(); } | |
| | | | |
| size_type total_payload_upload() const | | size_type total_payload_upload() const | |
| { return m_stat[upload_payload].total(); } | | { return m_stat[upload_payload].total(); } | |
| size_type total_payload_download() const | | size_type total_payload_download() const | |
| { return m_stat[download_payload].total(); } | | { return m_stat[download_payload].total(); } | |
| | | | |
| size_type total_protocol_upload() const | | size_type total_protocol_upload() const | |
| { return m_stat[upload_protocol].total(); } | | { return m_stat[upload_protocol].total(); } | |
| size_type total_protocol_download() const | | size_type total_protocol_download() const | |
| { return m_stat[download_protocol].total(); } | | { return m_stat[download_protocol].total(); } | |
| | | | |
|
| | | size_type total_transfer(int channel) const | |
| | | { return m_stat[channel].total(); } | |
| | | int transfer_rate(int channel) const | |
| | | { return m_stat[channel].rate(); } | |
| | | | |
| // this is used to offset the statistics when a | | // this is used to offset the statistics when a | |
| // peer_connection is opened and have some previous | | // peer_connection is opened and have some previous | |
| // transfers from earlier connections. | | // transfers from earlier connections. | |
| void add_stat(size_type downloaded, size_type uploaded) | | void add_stat(size_type downloaded, size_type uploaded) | |
| { | | { | |
|
| TORRENT_ASSERT(downloaded >= 0); | | | |
| TORRENT_ASSERT(uploaded >= 0); | | | |
| m_stat[download_payload].offset(downloaded); | | m_stat[download_payload].offset(downloaded); | |
| m_stat[upload_payload].offset(uploaded); | | m_stat[upload_payload].offset(uploaded); | |
| } | | } | |
| | | | |
| size_type last_payload_downloaded() const | | size_type last_payload_downloaded() const | |
| { return m_stat[download_payload].counter(); } | | { return m_stat[download_payload].counter(); } | |
| size_type last_payload_uploaded() const | | size_type last_payload_uploaded() const | |
| { return m_stat[upload_payload].counter(); } | | { return m_stat[upload_payload].counter(); } | |
|
| | | size_type last_protocol_downloaded() const | |
| void clear() | | { return m_stat[download_protocol].counter(); } | |
| { | | size_type last_protocol_uploaded() const | |
| for (int i = 0; i < num_channels; ++i) | | { return m_stat[upload_protocol].counter(); } | |
| m_stat[i].clear(); | | | |
| } | | | |
| | | | |
| private: | | | |
| | | | |
| // these are the channels we keep stats for | | // these are the channels we keep stats for | |
| enum | | enum | |
| { | | { | |
| upload_payload, | | upload_payload, | |
| upload_protocol, | | upload_protocol, | |
| upload_ip_protocol, | | upload_ip_protocol, | |
|
| | | upload_dht_protocol, | |
| | | upload_tracker_protocol, | |
| download_payload, | | download_payload, | |
| download_protocol, | | download_protocol, | |
| download_ip_protocol, | | download_ip_protocol, | |
|
| | | download_dht_protocol, | |
| | | download_tracker_protocol, | |
| num_channels | | num_channels | |
| }; | | }; | |
| | | | |
|
| | | void clear() | |
| | | { | |
| | | for (int i = 0; i < num_channels; ++i) | |
| | | m_stat[i].clear(); | |
| | | } | |
| | | | |
| | | stat_channel const& operator[](int i) const | |
| | | { | |
| | | TORRENT_ASSERT(i >= 0 && i < num_channels); | |
| | | return m_stat[i]; | |
| | | } | |
| | | | |
| | | private: | |
| | | | |
| stat_channel m_stat[num_channels]; | | stat_channel m_stat[num_channels]; | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_STAT_HPP_INCLUDED | | #endif // TORRENT_STAT_HPP_INCLUDED | |
| | | | |
End of changes. 26 change blocks. |
| 50 lines changed or deleted | | 130 lines changed or added | |
|
| storage.hpp | | storage.hpp | |
| | | | |
| skipping to change at line 60 | | skipping to change at line 60 | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(pop) | | #pragma warning(pop) | |
| #endif | | #endif | |
| | | | |
| #include "libtorrent/torrent_info.hpp" | | #include "libtorrent/torrent_info.hpp" | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/intrusive_ptr_base.hpp" | | #include "libtorrent/intrusive_ptr_base.hpp" | |
| #include "libtorrent/peer_request.hpp" | | #include "libtorrent/peer_request.hpp" | |
| #include "libtorrent/hasher.hpp" | | #include "libtorrent/hasher.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
|
| #include "libtorrent/buffer.hpp" | | #include "libtorrent/file.hpp" | |
| | | #include "libtorrent/disk_buffer_holder.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| namespace aux | | namespace aux | |
| { | | { | |
| struct piece_checker_data; | | struct piece_checker_data; | |
| } | | } | |
| | | | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| | | | |
| class session; | | class session; | |
| struct file_pool; | | struct file_pool; | |
| struct disk_io_job; | | struct disk_io_job; | |
|
| struct disk_buffer_holder; | | struct disk_buffer_pool; | |
| | | | |
| enum storage_mode_t | | enum storage_mode_t | |
| { | | { | |
| storage_mode_allocate = 0, | | storage_mode_allocate = 0, | |
| storage_mode_sparse, | | storage_mode_sparse, | |
| storage_mode_compact | | storage_mode_compact | |
| }; | | }; | |
| | | | |
|
| #if TORRENT_USE_WPATH | | | |
| | | | |
| TORRENT_EXPORT std::wstring safe_convert(std::string const& s); | | | |
| | | | |
| #endif | | | |
| | | | |
| TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_f
ilesizes( | | TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_f
ilesizes( | |
| file_storage const& t | | file_storage const& t | |
| , fs::path p); | | , fs::path p); | |
| | | | |
| TORRENT_EXPORT bool match_filesizes( | | TORRENT_EXPORT bool match_filesizes( | |
| file_storage const& t | | file_storage const& t | |
| , fs::path p | | , fs::path p | |
| , std::vector<std::pair<size_type, std::time_t> > const& siz
es | | , std::vector<std::pair<size_type, std::time_t> > const& siz
es | |
| , bool compact_mode | | , bool compact_mode | |
| , std::string* error = 0); | | , std::string* error = 0); | |
| | | | |
| skipping to change at line 119 | | skipping to change at line 114 | |
| { | | { | |
| partial_hash(): offset(0) {} | | partial_hash(): offset(0) {} | |
| // the number of bytes in the piece that has been hashed | | // the number of bytes in the piece that has been hashed | |
| int offset; | | int offset; | |
| // the sha-1 context | | // the sha-1 context | |
| hasher h; | | hasher h; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT storage_interface | | struct TORRENT_EXPORT storage_interface | |
| { | | { | |
|
| | | storage_interface(): m_disk_pool(0), m_settings(0) {} | |
| // create directories and set file sizes | | // create directories and set file sizes | |
| // if allocate_files is true. | | // if allocate_files is true. | |
| // allocate_files is true if allocation mode | | // allocate_files is true if allocation mode | |
| // is set to full and sparse files are supported | | // is set to full and sparse files are supported | |
| // false return value indicates an error | | // false return value indicates an error | |
| virtual bool initialize(bool allocate_files) = 0; | | virtual bool initialize(bool allocate_files) = 0; | |
| | | | |
| virtual bool has_any_file() = 0; | | virtual bool has_any_file() = 0; | |
| | | | |
|
| | | virtual int readv(file::iovec_t const* bufs, int slot, int o | |
| | | ffset, int num_bufs); | |
| | | virtual int writev(file::iovec_t const* bufs, int slot, int | |
| | | offset, int num_bufs); | |
| | | | |
| // negative return value indicates an error | | // negative return value indicates an error | |
| virtual int read(char* buf, int slot, int offset, int size)
= 0; | | virtual int read(char* buf, int slot, int offset, int size)
= 0; | |
| | | | |
| // negative return value indicates an error | | // negative return value indicates an error | |
| virtual int write(const char* buf, int slot, int offset, int
size) = 0; | | virtual int write(const char* buf, int slot, int offset, int
size) = 0; | |
| | | | |
|
| | | virtual size_type physical_offset(int slot, int offset) = 0; | |
| | | | |
| | | // returns the end of the sparse region the slot 'start' | |
| | | // resides in i.e. the next slot with content. If start | |
| | | // is not in a sparse region, start itself is returned | |
| | | virtual int sparse_end(int start) const { return start; } | |
| | | | |
| // non-zero return value indicates an error | | // non-zero return value indicates an error | |
| virtual bool move_storage(fs::path save_path) = 0; | | virtual bool move_storage(fs::path save_path) = 0; | |
| | | | |
| // verify storage dependent fast resume entries | | // verify storage dependent fast resume entries | |
|
| virtual bool verify_resume_data(lazy_entry const& rd, std::s
tring& error) = 0; | | virtual bool verify_resume_data(lazy_entry const& rd, error_
code& error) = 0; | |
| | | | |
| // write storage dependent fast resume entries | | // write storage dependent fast resume entries | |
| virtual bool write_resume_data(entry& rd) const = 0; | | virtual bool write_resume_data(entry& rd) const = 0; | |
| | | | |
| // moves (or copies) the content in src_slot to dst_slot | | // moves (or copies) the content in src_slot to dst_slot | |
| virtual bool move_slot(int src_slot, int dst_slot) = 0; | | virtual bool move_slot(int src_slot, int dst_slot) = 0; | |
| | | | |
| // swaps the data in slot1 and slot2 | | // swaps the data in slot1 and slot2 | |
| virtual bool swap_slots(int slot1, int slot2) = 0; | | virtual bool swap_slots(int slot1, int slot2) = 0; | |
| | | | |
| // swaps the puts the data in slot1 in slot2, the data in sl
ot2 | | // swaps the puts the data in slot1 in slot2, the data in sl
ot2 | |
| // in slot3 and the data in slot3 in slot1 | | // in slot3 and the data in slot3 in slot1 | |
| virtual bool swap_slots3(int slot1, int slot2, int slot3) =
0; | | virtual bool swap_slots3(int slot1, int slot2, int slot3) =
0; | |
| | | | |
|
| // returns the sha1-hash for the data at the given slot | | | |
| virtual sha1_hash hash_for_slot(int slot, partial_hash& h, i | | | |
| nt piece_size) = 0; | | | |
| | | | |
| // this will close all open files that are opened for | | // this will close all open files that are opened for | |
| // writing. This is called when a torrent has finished | | // writing. This is called when a torrent has finished | |
| // downloading. | | // downloading. | |
| // non-zero return value indicates an error | | // non-zero return value indicates an error | |
| virtual bool release_files() = 0; | | virtual bool release_files() = 0; | |
| | | | |
| // this will rename the file specified by index. | | // this will rename the file specified by index. | |
| virtual bool rename_file(int index, std::string const& new_f
ilename) = 0; | | virtual bool rename_file(int index, std::string const& new_f
ilename) = 0; | |
| | | | |
| // this will close all open files and delete them | | // this will close all open files and delete them | |
| // non-zero return value indicates an error | | // non-zero return value indicates an error | |
| virtual bool delete_files() = 0; | | virtual bool delete_files() = 0; | |
| | | | |
|
| | | disk_buffer_pool* disk_pool() { return m_disk_pool; } | |
| | | session_settings const& settings() const { return *m_setting | |
| | | s; } | |
| | | | |
| void set_error(boost::filesystem::path const& file, error_co
de const& ec) const | | void set_error(boost::filesystem::path const& file, error_co
de const& ec) const | |
| { | | { | |
| m_error_file = file.string(); | | m_error_file = file.string(); | |
| m_error = ec; | | m_error = ec; | |
| } | | } | |
| | | | |
| error_code const& error() const { return m_error; } | | error_code const& error() const { return m_error; } | |
| std::string const& error_file() const { return m_error_file;
} | | std::string const& error_file() const { return m_error_file;
} | |
| void clear_error() { m_error = error_code(); m_error_file.cl
ear(); } | | void clear_error() { m_error = error_code(); m_error_file.cl
ear(); } | |
| | | | |
| mutable error_code m_error; | | mutable error_code m_error; | |
| mutable std::string m_error_file; | | mutable std::string m_error_file; | |
| | | | |
| virtual ~storage_interface() {} | | virtual ~storage_interface() {} | |
|
| | | | |
| | | disk_buffer_pool* m_disk_pool; | |
| | | session_settings* m_settings; | |
| }; | | }; | |
| | | | |
|
| typedef storage_interface* (&storage_constructor_type)( | | typedef storage_interface* (*storage_constructor_type)( | |
| file_storage const&, file_storage const*, fs::path const&, f
ile_pool&); | | file_storage const&, file_storage const*, fs::path const&, f
ile_pool&); | |
| | | | |
| TORRENT_EXPORT storage_interface* default_storage_constructor( | | TORRENT_EXPORT storage_interface* default_storage_constructor( | |
| file_storage const&, file_storage const* mapped, fs::path co
nst&, file_pool&); | | file_storage const&, file_storage const* mapped, fs::path co
nst&, file_pool&); | |
| | | | |
|
| | | TORRENT_EXPORT storage_interface* disabled_storage_constructor( | |
| | | file_storage const&, file_storage const* mapped, fs::path co | |
| | | nst&, file_pool&); | |
| | | | |
| struct disk_io_thread; | | struct disk_io_thread; | |
| | | | |
| class TORRENT_EXPORT piece_manager | | class TORRENT_EXPORT piece_manager | |
| : public intrusive_ptr_base<piece_manager> | | : public intrusive_ptr_base<piece_manager> | |
| , boost::noncopyable | | , boost::noncopyable | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| friend struct disk_io_thread; | | friend struct disk_io_thread; | |
| public: | | public: | |
| | | | |
| | | | |
| skipping to change at line 220 | | skipping to change at line 232 | |
| ~piece_manager(); | | ~piece_manager(); | |
| | | | |
| boost::intrusive_ptr<torrent_info const> info() const { retu
rn m_info; } | | boost::intrusive_ptr<torrent_info const> info() const { retu
rn m_info; } | |
| void write_resume_data(entry& rd) const; | | void write_resume_data(entry& rd) const; | |
| | | | |
| void async_check_fastresume(lazy_entry const* resume_data | | void async_check_fastresume(lazy_entry const* resume_data | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler); | | , boost::function<void(int, disk_io_job const&)> con
st& handler); | |
| | | | |
| void async_check_files(boost::function<void(int, disk_io_job
const&)> const& handler); | | void async_check_files(boost::function<void(int, disk_io_job
const&)> const& handler); | |
| | | | |
|
| | | int queued_bytes() const; | |
| | | | |
| void async_rename_file(int index, std::string const& name | | void async_rename_file(int index, std::string const& name | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler); | | , boost::function<void(int, disk_io_job const&)> con
st& handler); | |
| | | | |
| void async_read( | | void async_read( | |
| peer_request const& r | | peer_request const& r | |
| , boost::function<void(int, disk_io_job const&)> con
st& handler | | , boost::function<void(int, disk_io_job const&)> con
st& handler | |
| , int priority = 0); | | , int priority = 0); | |
| | | | |
|
| | | void async_read_and_hash( | |
| | | peer_request const& r | |
| | | , boost::function<void(int, disk_io_job const&)> con | |
| | | st& handler | |
| | | , int priority = 0); | |
| | | | |
| void async_write( | | void async_write( | |
| peer_request const& r | | peer_request const& r | |
| , disk_buffer_holder& buffer | | , disk_buffer_holder& buffer | |
| , boost::function<void(int, disk_io_job const&)> con
st& f); | | , boost::function<void(int, disk_io_job const&)> con
st& f); | |
| | | | |
| void async_hash(int piece, boost::function<void(int, disk_io
_job const&)> const& f); | | void async_hash(int piece, boost::function<void(int, disk_io
_job const&)> const& f); | |
| | | | |
| void async_release_files( | | void async_release_files( | |
| boost::function<void(int, disk_io_job const&)> const
& handler | | boost::function<void(int, disk_io_job const&)> const
& handler | |
| = boost::function<void(int, disk_io_job const&)>()); | | = boost::function<void(int, disk_io_job const&)>()); | |
| | | | |
| skipping to change at line 270 | | skipping to change at line 289 | |
| fatal_disk_error = -2, | | fatal_disk_error = -2, | |
| disk_check_aborted = -3 | | disk_check_aborted = -3 | |
| }; | | }; | |
| | | | |
| storage_interface* get_storage_impl() { return m_storage.get
(); } | | storage_interface* get_storage_impl() { return m_storage.get
(); } | |
| | | | |
| private: | | private: | |
| | | | |
| fs::path save_path() const; | | fs::path save_path() const; | |
| | | | |
|
| bool verify_resume_data(lazy_entry const& rd, std::string& e | | bool verify_resume_data(lazy_entry const& rd, error_code& e) | |
| rror) | | { return m_storage->verify_resume_data(rd, e); } | |
| { return m_storage->verify_resume_data(rd, error); } | | | |
| | | | |
| bool is_allocating() const | | bool is_allocating() const | |
| { return m_state == state_expand_pieces; } | | { return m_state == state_expand_pieces; } | |
| | | | |
| void mark_failed(int index); | | void mark_failed(int index); | |
| | | | |
| error_code const& error() const { return m_storage->error();
} | | error_code const& error() const { return m_storage->error();
} | |
| std::string const& error_file() const { return m_storage->er
ror_file(); } | | std::string const& error_file() const { return m_storage->er
ror_file(); } | |
|
| | | int last_piece() const { return m_last_piece; } | |
| | | int last_operation() const { return m_last_op; } | |
| void clear_error() { m_storage->clear_error(); } | | void clear_error() { m_storage->clear_error(); } | |
| | | | |
| int slot_for(int piece) const; | | int slot_for(int piece) const; | |
| int piece_for(int slot) const; | | int piece_for(int slot) const; | |
| | | | |
| // helper functions for check_dastresume | | // helper functions for check_dastresume | |
|
| int check_no_fastresume(std::string& error); | | int check_no_fastresume(error_code& error); | |
| int check_init_storage(std::string& error); | | int check_init_storage(error_code& error); | |
| | | | |
| // if error is set and return value is 'no_error' or 'need_f
ull_check' | | // if error is set and return value is 'no_error' or 'need_f
ull_check' | |
| // the error message indicates that the fast resume data was
rejected | | // the error message indicates that the fast resume data was
rejected | |
| // if 'fatal_disk_error' is returned, the error message indi
cates what | | // if 'fatal_disk_error' is returned, the error message indi
cates what | |
| // when wrong in the disk access | | // when wrong in the disk access | |
|
| int check_fastresume(lazy_entry const& rd, std::string& erro
r); | | int check_fastresume(lazy_entry const& rd, error_code& error
); | |
| | | | |
| // this function returns true if the checking is complete | | // this function returns true if the checking is complete | |
|
| int check_files(int& current_slot, int& have_piece, std::str
ing& error); | | int check_files(int& current_slot, int& have_piece, error_co
de& error); | |
| | | | |
| bool compact_allocation() const | | bool compact_allocation() const | |
| { return m_storage_mode == storage_mode_compact; } | | { return m_storage_mode == storage_mode_compact; } | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| std::string name() const { return m_info->name(); } | | std::string name() const { return m_info->name(); } | |
| #endif | | #endif | |
| | | | |
| bool allocate_slots(int num_slots, bool abort_on_disk = fals
e); | | bool allocate_slots(int num_slots, bool abort_on_disk = fals
e); | |
| | | | |
|
| | | // updates the ph.h hasher object with the data at the given | |
| | | slot | |
| | | // and optionally a 'small hash' as well, the hash for | |
| | | // the partial slot. Returns the number of bytes read | |
| | | int hash_for_slot(int slot, partial_hash& h, int piece_size | |
| | | , int small_piece_size = 0, sha1_hash* small_hash = | |
| | | 0); | |
| | | | |
| int read_impl( | | int read_impl( | |
|
| char* buf | | file::iovec_t* bufs | |
| , int piece_index | | , int piece_index | |
| , int offset | | , int offset | |
|
| , int size); | | , int num_bufs); | |
| | | | |
| int write_impl( | | int write_impl( | |
|
| const char* buf | | file::iovec_t* bufs | |
| , int piece_index | | , int piece_index | |
| , int offset | | , int offset | |
|
| , int size); | | , int num_bufs); | |
| | | | |
|
| // -1=error 0=ok 1=skip | | size_type physical_offset(int piece_index, int offset); | |
| | | | |
| | | // returns the number of pieces left in the | |
| | | // file currently being checked | |
| | | int skip_file() const; | |
| | | // -1=error 0=ok >0=skip this many pieces | |
| int check_one_piece(int& have_piece); | | int check_one_piece(int& have_piece); | |
| int identify_data( | | int identify_data( | |
|
| const std::vector<char>& piece_data | | sha1_hash const& large_hash | |
| | | , sha1_hash const& small_hash | |
| , int current_slot); | | , int current_slot); | |
| | | | |
| void switch_to_full_mode(); | | void switch_to_full_mode(); | |
| sha1_hash hash_for_piece_impl(int piece); | | sha1_hash hash_for_piece_impl(int piece); | |
| | | | |
| int release_files_impl() { return m_storage->release_files()
; } | | int release_files_impl() { return m_storage->release_files()
; } | |
| int delete_files_impl() { return m_storage->delete_files();
} | | int delete_files_impl() { return m_storage->delete_files();
} | |
| int rename_file_impl(int index, std::string const& new_filen
ame) | | int rename_file_impl(int index, std::string const& new_filen
ame) | |
| { return m_storage->rename_file(index, new_filename); } | | { return m_storage->rename_file(index, new_filename); } | |
| | | | |
| | | | |
| skipping to change at line 395 | | skipping to change at line 428 | |
| state_expand_pieces | | state_expand_pieces | |
| } m_state; | | } m_state; | |
| int m_current_slot; | | int m_current_slot; | |
| // used during check. If any piece is found | | // used during check. If any piece is found | |
| // that is not in its final position, this | | // that is not in its final position, this | |
| // is set to true | | // is set to true | |
| bool m_out_of_place; | | bool m_out_of_place; | |
| // used to move pieces while expanding | | // used to move pieces while expanding | |
| // the storage from compact allocation | | // the storage from compact allocation | |
| // to full allocation | | // to full allocation | |
|
| buffer m_scratch_buffer; | | disk_buffer_holder m_scratch_buffer; | |
| buffer m_scratch_buffer2; | | disk_buffer_holder m_scratch_buffer2; | |
| // the piece that is in the scratch buffer | | // the piece that is in the scratch buffer | |
| int m_scratch_piece; | | int m_scratch_piece; | |
| | | | |
|
| | | // the last piece we wrote to or read from | |
| | | int m_last_piece; | |
| | | | |
| | | // the last operation we did (read or write) | |
| | | int m_last_op; | |
| | | | |
| // this is saved in case we need to instantiate a new | | // this is saved in case we need to instantiate a new | |
| // storage (osed when remapping files) | | // storage (osed when remapping files) | |
| storage_constructor_type m_storage_constructor; | | storage_constructor_type m_storage_constructor; | |
| | | | |
|
| // temporary buffer used while checking | | | |
| std::vector<char> m_piece_data; | | | |
| | | | |
| // this maps a piece hash to piece index. It will be | | // this maps a piece hash to piece index. It will be | |
| // build the first time it is used (to save time if it | | // build the first time it is used (to save time if it | |
| // isn't needed) | | // isn't needed) | |
| std::multimap<sha1_hash, int> m_hash_to_piece; | | std::multimap<sha1_hash, int> m_hash_to_piece; | |
| | | | |
| // this map contains partial hashes for downloading | | // this map contains partial hashes for downloading | |
| // pieces. This is only accessed from within the | | // pieces. This is only accessed from within the | |
| // disk-io thread. | | // disk-io thread. | |
| std::map<int, partial_hash> m_piece_hasher; | | std::map<int, partial_hash> m_piece_hasher; | |
| | | | |
| | | | |
End of changes. 29 change blocks. |
| 32 lines changed or deleted | | 73 lines changed or added | |
|
| time.hpp | | time.hpp | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_TIME_HPP_INCLUDED | | #ifndef TORRENT_TIME_HPP_INCLUDED | |
| #define TORRENT_TIME_HPP_INCLUDED | | #define TORRENT_TIME_HPP_INCLUDED | |
| | | | |
| #include <ctime> | | #include <ctime> | |
| #include <boost/version.hpp> | | #include <boost/version.hpp> | |
|
| | | #include "libtorrent/config.hpp" | |
| | | | |
| #ifndef _WIN32 | | #ifndef _WIN32 | |
| #include <unistd.h> | | #include <unistd.h> | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| inline char const* time_now_string() | | inline char const* time_now_string() | |
| { | | { | |
| time_t t = std::time(0); | | time_t t = std::time(0); | |
| tm* timeinfo = std::localtime(&t); | | tm* timeinfo = std::localtime(&t); | |
| static char str[200]; | | static char str[200]; | |
| std::strftime(str, 200, "%b %d %X", timeinfo); | | std::strftime(str, 200, "%b %d %X", timeinfo); | |
| return str; | | return str; | |
| } | | } | |
| | | | |
| std::string log_time(); | | std::string log_time(); | |
| } | | } | |
| | | | |
|
| #if (!defined (__MACH__) && !defined (_WIN32) && (!defined(_POSIX_MONOTONIC | | #if defined TORRENT_USE_BOOST_DATE_TIME | |
| _CLOCK) \ | | | |
| || _POSIX_MONOTONIC_CLOCK < 0)) || defined (TORRENT_USE_BOOST_DATE_T | | | |
| IME) | | | |
| | | | |
| #include <boost/date_time/posix_time/posix_time_types.hpp> | | #include <boost/date_time/posix_time/posix_time_types.hpp> | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| typedef boost::posix_time::ptime ptime; | | typedef boost::posix_time::ptime ptime; | |
| typedef boost::posix_time::time_duration time_duration; | | typedef boost::posix_time::time_duration time_duration; | |
|
| inline ptime time_now() | | inline ptime time_now_hires() | |
| { return boost::posix_time::microsec_clock::universal_time(); } | | { return boost::posix_time::microsec_clock::universal_time(); } | |
| inline ptime min_time() | | inline ptime min_time() | |
| { return boost::posix_time::ptime(boost::posix_time::min_date_time);
} | | { return boost::posix_time::ptime(boost::posix_time::min_date_time);
} | |
| inline ptime max_time() | | inline ptime max_time() | |
| { return boost::posix_time::ptime(boost::posix_time::max_date_time);
} | | { return boost::posix_time::ptime(boost::posix_time::max_date_time);
} | |
| inline time_duration seconds(int s) { return boost::posix_time::seco
nds(s); } | | inline time_duration seconds(int s) { return boost::posix_time::seco
nds(s); } | |
| inline time_duration milliseconds(int s) { return boost::posix_time:
:milliseconds(s); } | | inline time_duration milliseconds(int s) { return boost::posix_time:
:milliseconds(s); } | |
| inline time_duration microsec(int s) { return boost::posix_time::mic
rosec(s); } | | inline time_duration microsec(int s) { return boost::posix_time::mic
rosec(s); } | |
| inline time_duration minutes(int s) { return boost::posix_time::minu
tes(s); } | | inline time_duration minutes(int s) { return boost::posix_time::minu
tes(s); } | |
| inline time_duration hours(int s) { return boost::posix_time::hours(
s); } | | inline time_duration hours(int s) { return boost::posix_time::hours(
s); } | |
| | | | |
| inline int total_seconds(time_duration td) | | inline int total_seconds(time_duration td) | |
| { return td.total_seconds(); } | | { return td.total_seconds(); } | |
| inline int total_milliseconds(time_duration td) | | inline int total_milliseconds(time_duration td) | |
| { return td.total_milliseconds(); } | | { return td.total_milliseconds(); } | |
| inline boost::int64_t total_microseconds(time_duration td) | | inline boost::int64_t total_microseconds(time_duration td) | |
| { return td.total_microseconds(); } | | { return td.total_microseconds(); } | |
| | | | |
| } | | } | |
| | | | |
|
| #else | | #else // TORRENT_USE_BOOST_DATE_TIME | |
| | | | |
| #if BOOST_VERSION < 103500 | | #if BOOST_VERSION < 103500 | |
| #include <asio/time_traits.hpp> | | #include <asio/time_traits.hpp> | |
| #else | | #else | |
| #include <boost/asio/time_traits.hpp> | | #include <boost/asio/time_traits.hpp> | |
| #endif | | #endif | |
| #include <boost/cstdint.hpp> | | #include <boost/cstdint.hpp> | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| // libtorrent time_duration type | | // libtorrent time_duration type | |
| struct time_duration | | struct time_duration | |
| { | | { | |
| time_duration() {} | | time_duration() {} | |
| time_duration operator/(int rhs) const { return time_duratio
n(diff / rhs); } | | time_duration operator/(int rhs) const { return time_duratio
n(diff / rhs); } | |
| explicit time_duration(boost::int64_t d) : diff(d) {} | | explicit time_duration(boost::int64_t d) : diff(d) {} | |
| time_duration& operator-=(time_duration const& c) { diff -=
c.diff; return *this; } | | time_duration& operator-=(time_duration const& c) { diff -=
c.diff; return *this; } | |
| time_duration& operator+=(time_duration const& c) { diff +=
c.diff; return *this; } | | time_duration& operator+=(time_duration const& c) { diff +=
c.diff; return *this; } | |
| time_duration operator+(time_duration const& c) { return tim
e_duration(diff + c.diff); } | | time_duration operator+(time_duration const& c) { return tim
e_duration(diff + c.diff); } | |
|
| | | time_duration operator-(time_duration const& c) { return tim
e_duration(diff - c.diff); } | |
| boost::int64_t diff; | | boost::int64_t diff; | |
| }; | | }; | |
| | | | |
| inline bool is_negative(time_duration dt) { return dt.diff < 0; } | | inline bool is_negative(time_duration dt) { return dt.diff < 0; } | |
|
| | | inline bool operator==(time_duration lhs, time_duration rhs) | |
| | | { return lhs.diff == rhs.diff; } | |
| inline bool operator<(time_duration lhs, time_duration rhs) | | inline bool operator<(time_duration lhs, time_duration rhs) | |
| { return lhs.diff < rhs.diff; } | | { return lhs.diff < rhs.diff; } | |
| inline bool operator<=(time_duration lhs, time_duration rhs) | | inline bool operator<=(time_duration lhs, time_duration rhs) | |
| { return lhs.diff <= rhs.diff; } | | { return lhs.diff <= rhs.diff; } | |
| inline bool operator>(time_duration lhs, time_duration rhs) | | inline bool operator>(time_duration lhs, time_duration rhs) | |
| { return lhs.diff > rhs.diff; } | | { return lhs.diff > rhs.diff; } | |
| inline bool operator>=(time_duration lhs, time_duration rhs) | | inline bool operator>=(time_duration lhs, time_duration rhs) | |
| { return lhs.diff >= rhs.diff; } | | { return lhs.diff >= rhs.diff; } | |
|
| | | inline time_duration operator*(time_duration lhs, int rhs) | |
| | | { return time_duration(boost::int64_t(lhs.diff * rhs)); } | |
| | | inline time_duration operator*(int lhs, time_duration rhs) | |
| | | { return time_duration(boost::int64_t(lhs * rhs.diff)); } | |
| | | | |
| // libtorrent time type | | // libtorrent time type | |
| struct ptime | | struct ptime | |
| { | | { | |
| ptime() {} | | ptime() {} | |
|
| explicit ptime(boost::int64_t t): time(t) {} | | explicit ptime(boost::uint64_t t): time(t) {} | |
| ptime& operator+=(time_duration rhs) { time += rhs.diff; ret
urn *this; } | | ptime& operator+=(time_duration rhs) { time += rhs.diff; ret
urn *this; } | |
| ptime& operator-=(time_duration rhs) { time -= rhs.diff; ret
urn *this; } | | ptime& operator-=(time_duration rhs) { time -= rhs.diff; ret
urn *this; } | |
|
| boost::int64_t time; | | boost::uint64_t time; | |
| }; | | }; | |
| | | | |
| inline bool operator>(ptime lhs, ptime rhs) | | inline bool operator>(ptime lhs, ptime rhs) | |
| { return lhs.time > rhs.time; } | | { return lhs.time > rhs.time; } | |
| inline bool operator>=(ptime lhs, ptime rhs) | | inline bool operator>=(ptime lhs, ptime rhs) | |
| { return lhs.time >= rhs.time; } | | { return lhs.time >= rhs.time; } | |
| inline bool operator<=(ptime lhs, ptime rhs) | | inline bool operator<=(ptime lhs, ptime rhs) | |
| { return lhs.time <= rhs.time; } | | { return lhs.time <= rhs.time; } | |
| inline bool operator<(ptime lhs, ptime rhs) | | inline bool operator<(ptime lhs, ptime rhs) | |
| { return lhs.time < rhs.time; } | | { return lhs.time < rhs.time; } | |
| | | | |
| skipping to change at line 153 | | skipping to change at line 160 | |
| { return lhs.time == rhs.time;} | | { return lhs.time == rhs.time;} | |
| inline time_duration operator-(ptime lhs, ptime rhs) | | inline time_duration operator-(ptime lhs, ptime rhs) | |
| { return time_duration(lhs.time - rhs.time); } | | { return time_duration(lhs.time - rhs.time); } | |
| inline ptime operator+(ptime lhs, time_duration rhs) | | inline ptime operator+(ptime lhs, time_duration rhs) | |
| { return ptime(lhs.time + rhs.diff); } | | { return ptime(lhs.time + rhs.diff); } | |
| inline ptime operator+(time_duration lhs, ptime rhs) | | inline ptime operator+(time_duration lhs, ptime rhs) | |
| { return ptime(rhs.time + lhs.diff); } | | { return ptime(rhs.time + lhs.diff); } | |
| inline ptime operator-(ptime lhs, time_duration rhs) | | inline ptime operator-(ptime lhs, time_duration rhs) | |
| { return ptime(lhs.time - rhs.diff); } | | { return ptime(lhs.time - rhs.diff); } | |
| | | | |
|
| ptime time_now(); | | ptime time_now_hires(); | |
| inline ptime min_time() { return ptime(0); } | | inline ptime min_time() { return ptime(0); } | |
|
| inline ptime max_time() { return ptime((std::numeric_limits<boost::i
nt64_t>::max)()); } | | inline ptime max_time() { return ptime((std::numeric_limits<boost::u
int64_t>::max)()); } | |
| int total_seconds(time_duration td); | | int total_seconds(time_duration td); | |
| int total_milliseconds(time_duration td); | | int total_milliseconds(time_duration td); | |
| boost::int64_t total_microseconds(time_duration td); | | boost::int64_t total_microseconds(time_duration td); | |
| } | | } | |
| | | | |
| // asio time_traits | | // asio time_traits | |
| #if BOOST_VERSION >= 103500 | | #if BOOST_VERSION >= 103500 | |
| namespace boost { | | namespace boost { | |
| #endif | | #endif | |
| namespace asio | | namespace asio | |
| { | | { | |
| template<> | | template<> | |
| struct time_traits<libtorrent::ptime> | | struct time_traits<libtorrent::ptime> | |
| { | | { | |
| typedef libtorrent::ptime time_type; | | typedef libtorrent::ptime time_type; | |
| typedef libtorrent::time_duration duration_type; | | typedef libtorrent::time_duration duration_type; | |
| static time_type now() | | static time_type now() | |
|
| { return time_type(libtorrent::time_now()); } | | { return time_type(libtorrent::time_now_hires()); } | |
| static time_type add(time_type t, duration_type d) | | static time_type add(time_type t, duration_type d) | |
| { return time_type(t.time + d.diff);} | | { return time_type(t.time + d.diff);} | |
| static duration_type subtract(time_type t1, time_type t2) | | static duration_type subtract(time_type t1, time_type t2) | |
| { return duration_type(t1 - t2); } | | { return duration_type(t1 - t2); } | |
| static bool less_than(time_type t1, time_type t2) | | static bool less_than(time_type t1, time_type t2) | |
| { return t1 < t2; } | | { return t1 < t2; } | |
| static boost::posix_time::time_duration to_posix_duration( | | static boost::posix_time::time_duration to_posix_duration( | |
| duration_type d) | | duration_type d) | |
| { return boost::posix_time::microseconds(libtorrent::total_m
icroseconds(d)); } | | { return boost::posix_time::microseconds(libtorrent::total_m
icroseconds(d)); } | |
| }; | | }; | |
| } | | } | |
| #if BOOST_VERSION >= 103500 | | #if BOOST_VERSION >= 103500 | |
| } | | } | |
| #endif | | #endif | |
| | | | |
|
| #if defined(__MACH__) | | #if defined TORRENT_USE_ABSOLUTE_TIME | |
| | | | |
| #include <mach/mach_time.h> | | #include <mach/mach_time.h> | |
| #include <boost/cstdint.hpp> | | #include <boost/cstdint.hpp> | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| | | | |
| // high precision timer for darwin intel and ppc | | // high precision timer for darwin intel and ppc | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
|
| namespace aux | | | |
| { | | | |
| inline boost::int64_t absolutetime_to_microseconds(boost::in | | | |
| t64_t at) | | | |
| { | | | |
| static mach_timebase_info_data_t timebase_info = {0, | | | |
| 0}; | | | |
| if (timebase_info.denom == 0) | | | |
| mach_timebase_info(&timebase_info); | | | |
| // make sure we don't overflow | | | |
| TORRENT_ASSERT((at >= 0 && at >= at / 1000 * timebas | | | |
| e_info.numer / timebase_info.denom) | | | |
| || (at < 0 && at < at / 1000 * timebase_info | | | |
| .numer / timebase_info.denom)); | | | |
| return at / 1000 * timebase_info.numer / timebase_in | | | |
| fo.denom; | | | |
| } | | | |
| | | | |
| inline boost::int64_t microseconds_to_absolutetime(boost::in | | | |
| t64_t ms) | | | |
| { | | | |
| static mach_timebase_info_data_t timebase_info = {0, | | | |
| 0}; | | | |
| if (timebase_info.denom == 0) | | | |
| { | | | |
| mach_timebase_info(&timebase_info); | | | |
| TORRENT_ASSERT(timebase_info.numer > 0); | | | |
| TORRENT_ASSERT(timebase_info.denom > 0); | | | |
| } | | | |
| // make sure we don't overflow | | | |
| TORRENT_ASSERT((ms >= 0 && ms <= ms * timebase_info. | | | |
| denom / timebase_info.numer * 1000) | | | |
| || (ms < 0 && ms > ms * timebase_info.denom | | | |
| / timebase_info.numer * 1000)); | | | |
| return ms * timebase_info.denom / timebase_info.nume | | | |
| r * 1000; | | | |
| } | | | |
| } | | | |
| | | | |
| inline int total_seconds(time_duration td) | | inline int total_seconds(time_duration td) | |
| { | | { | |
|
| return aux::absolutetime_to_microseconds(td.diff) | | return td.diff / 1000000; | |
| / 1000000; | | | |
| } | | } | |
| inline int total_milliseconds(time_duration td) | | inline int total_milliseconds(time_duration td) | |
| { | | { | |
|
| return aux::absolutetime_to_microseconds(td.diff) | | return td.diff / 1000; | |
| / 1000; | | | |
| } | | } | |
| inline boost::int64_t total_microseconds(time_duration td) | | inline boost::int64_t total_microseconds(time_duration td) | |
| { | | { | |
|
| return aux::absolutetime_to_microseconds(td.diff); | | return td.diff; | |
| } | | } | |
| | | | |
|
| inline ptime time_now() { return ptime(mach_absolute_time()); } | | inline ptime time_now_hires() | |
| | | { | |
| | | static mach_timebase_info_data_t timebase_info = {0,0}; | |
| | | if (timebase_info.denom == 0) | |
| | | mach_timebase_info(&timebase_info); | |
| | | boost::uint64_t at = mach_absolute_time(); | |
| | | // make sure we don't overflow | |
| | | TORRENT_ASSERT((at >= 0 && at >= at / 1000 * timebase_info.n | |
| | | umer / timebase_info.denom) | |
| | | || (at < 0 && at < at / 1000 * timebase_info.numer / | |
| | | timebase_info.denom)); | |
| | | return ptime(at / 1000 * timebase_info.numer / timebase_info | |
| | | .denom); | |
| | | } | |
| | | | |
| inline time_duration microsec(boost::int64_t s) | | inline time_duration microsec(boost::int64_t s) | |
| { | | { | |
|
| return time_duration(aux::microseconds_to_absolutetime(s)); | | return time_duration(s); | |
| } | | } | |
| inline time_duration milliseconds(boost::int64_t s) | | inline time_duration milliseconds(boost::int64_t s) | |
| { | | { | |
|
| return time_duration(aux::microseconds_to_absolutetime(s * 1
000)); | | return time_duration(s * 1000); | |
| } | | } | |
| inline time_duration seconds(boost::int64_t s) | | inline time_duration seconds(boost::int64_t s) | |
| { | | { | |
|
| return time_duration(aux::microseconds_to_absolutetime(s * 1
000000)); | | return time_duration(s * 1000000); | |
| } | | } | |
| inline time_duration minutes(boost::int64_t s) | | inline time_duration minutes(boost::int64_t s) | |
| { | | { | |
|
| return time_duration(aux::microseconds_to_absolutetime(s * 1
000000 * 60)); | | return time_duration(s * 1000000 * 60); | |
| } | | } | |
| inline time_duration hours(boost::int64_t s) | | inline time_duration hours(boost::int64_t s) | |
| { | | { | |
|
| return time_duration(aux::microseconds_to_absolutetime(s * 1
000000 * 60 * 60)); | | return time_duration(s * 1000000 * 60 * 60); | |
| } | | } | |
| | | | |
| } | | } | |
|
| #elif defined(_WIN32) | | #elif defined TORRENT_USE_QUERY_PERFORMANCE_TIMER | |
| | | | |
| #ifndef WIN32_LEAN_AND_MEAN | | #ifndef WIN32_LEAN_AND_MEAN | |
| #define WIN32_LEAN_AND_MEAN | | #define WIN32_LEAN_AND_MEAN | |
| #endif | | #endif | |
| #include <windows.h> | | #include <windows.h> | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| namespace aux | | namespace aux | |
| | | | |
| skipping to change at line 323 | | skipping to change at line 309 | |
| inline int total_milliseconds(time_duration td) | | inline int total_milliseconds(time_duration td) | |
| { | | { | |
| return int(aux::performance_counter_to_microseconds(td.diff) | | return int(aux::performance_counter_to_microseconds(td.diff) | |
| / 1000); | | / 1000); | |
| } | | } | |
| inline boost::int64_t total_microseconds(time_duration td) | | inline boost::int64_t total_microseconds(time_duration td) | |
| { | | { | |
| return aux::performance_counter_to_microseconds(td.diff); | | return aux::performance_counter_to_microseconds(td.diff); | |
| } | | } | |
| | | | |
|
| inline ptime time_now() | | inline ptime time_now_hires() | |
| { | | { | |
| LARGE_INTEGER now; | | LARGE_INTEGER now; | |
| QueryPerformanceCounter(&now); | | QueryPerformanceCounter(&now); | |
| return ptime(now.QuadPart); | | return ptime(now.QuadPart); | |
| } | | } | |
| | | | |
| inline time_duration microsec(boost::int64_t s) | | inline time_duration microsec(boost::int64_t s) | |
| { | | { | |
| return time_duration(aux::microseconds_to_performance_counte
r(s)); | | return time_duration(aux::microseconds_to_performance_counte
r(s)); | |
| } | | } | |
| | | | |
| skipping to change at line 357 | | skipping to change at line 343 | |
| s * 1000000 * 60)); | | s * 1000000 * 60)); | |
| } | | } | |
| inline time_duration hours(boost::int64_t s) | | inline time_duration hours(boost::int64_t s) | |
| { | | { | |
| return time_duration(aux::microseconds_to_performance_counte
r( | | return time_duration(aux::microseconds_to_performance_counte
r( | |
| s * 1000000 * 60 * 60)); | | s * 1000000 * 60 * 60)); | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
|
| #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 | | #elif defined TORRENT_USE_CLOCK_GETTIME | |
| | | | |
| #include <time.h> | | #include <time.h> | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| inline int total_seconds(time_duration td) | | inline int total_seconds(time_duration td) | |
| { | | { | |
| return td.diff / 1000000; | | return td.diff / 1000000; | |
| } | | } | |
| inline int total_milliseconds(time_duration td) | | inline int total_milliseconds(time_duration td) | |
| { | | { | |
| return td.diff / 1000; | | return td.diff / 1000; | |
| } | | } | |
| inline boost::int64_t total_microseconds(time_duration td) | | inline boost::int64_t total_microseconds(time_duration td) | |
| { | | { | |
| return td.diff; | | return td.diff; | |
| } | | } | |
| | | | |
|
| inline ptime time_now() | | inline ptime time_now_hires() | |
| { | | { | |
| timespec ts; | | timespec ts; | |
| clock_gettime(CLOCK_MONOTONIC, &ts); | | clock_gettime(CLOCK_MONOTONIC, &ts); | |
|
| return ptime(boost::int64_t(ts.tv_sec) * 1000000 + ts.tv_nse
c / 1000); | | return ptime(boost::uint64_t(ts.tv_sec) * 1000000 + ts.tv_ns
ec / 1000); | |
| } | | } | |
| | | | |
| inline time_duration microsec(boost::int64_t s) | | inline time_duration microsec(boost::int64_t s) | |
| { | | { | |
| return time_duration(s); | | return time_duration(s); | |
| } | | } | |
| inline time_duration milliseconds(boost::int64_t s) | | inline time_duration milliseconds(boost::int64_t s) | |
| { | | { | |
| return time_duration(s * 1000); | | return time_duration(s * 1000); | |
| } | | } | |
| | | | |
| skipping to change at line 407 | | skipping to change at line 393 | |
| { | | { | |
| return time_duration(s * 1000000 * 60); | | return time_duration(s * 1000000 * 60); | |
| } | | } | |
| inline time_duration hours(boost::int64_t s) | | inline time_duration hours(boost::int64_t s) | |
| { | | { | |
| return time_duration(s * 1000000 * 60 * 60); | | return time_duration(s * 1000000 * 60 * 60); | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
|
| #endif | | #endif // TORRENT_USE_CLOCK_GETTIME | |
| | | | |
|
| #endif | | #endif // TORRENT_USE_BOOST_DATE_TIME | |
| | | | |
|
| #endif | | namespace libtorrent | |
| | | { | |
| | | TORRENT_EXPORT ptime const& time_now(); | |
| | | } | |
| | | | |
| | | #endif // TORRENT_TIME_HPP_INCLUDED | |
| | | | |
End of changes. 31 change blocks. |
| 69 lines changed or deleted | | 46 lines changed or added | |
|
| torrent.hpp | | torrent.hpp | |
| | | | |
| skipping to change at line 40 | | skipping to change at line 40 | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_TORRENT_HPP_INCLUDE | | #ifndef TORRENT_TORRENT_HPP_INCLUDE | |
| #define TORRENT_TORRENT_HPP_INCLUDE | | #define TORRENT_TORRENT_HPP_INCLUDE | |
| | | | |
| #include <algorithm> | | #include <algorithm> | |
| #include <vector> | | #include <vector> | |
| #include <set> | | #include <set> | |
| #include <list> | | #include <list> | |
|
| #include <iostream> | | | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/limits.hpp> | | #include <boost/limits.hpp> | |
| #include <boost/filesystem/path.hpp> | | #include <boost/filesystem/path.hpp> | |
| #include <boost/tuple/tuple.hpp> | | #include <boost/tuple/tuple.hpp> | |
| #include <boost/enable_shared_from_this.hpp> | | #include <boost/enable_shared_from_this.hpp> | |
| #include <boost/scoped_ptr.hpp> | | #include <boost/scoped_ptr.hpp> | |
| | | | |
| skipping to change at line 74 | | skipping to change at line 73 | |
| #include "libtorrent/alert.hpp" | | #include "libtorrent/alert.hpp" | |
| #include "libtorrent/piece_picker.hpp" | | #include "libtorrent/piece_picker.hpp" | |
| #include "libtorrent/config.hpp" | | #include "libtorrent/config.hpp" | |
| #include "libtorrent/escape_string.hpp" | | #include "libtorrent/escape_string.hpp" | |
| #include "libtorrent/bandwidth_limit.hpp" | | #include "libtorrent/bandwidth_limit.hpp" | |
| #include "libtorrent/bandwidth_queue_entry.hpp" | | #include "libtorrent/bandwidth_queue_entry.hpp" | |
| #include "libtorrent/storage.hpp" | | #include "libtorrent/storage.hpp" | |
| #include "libtorrent/hasher.hpp" | | #include "libtorrent/hasher.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/bitfield.hpp" | | #include "libtorrent/bitfield.hpp" | |
|
| | | #include "libtorrent/aux_/session_impl.hpp" | |
| | | | |
| #if TORRENT_COMPLETE_TYPES_REQUIRED | | #if TORRENT_COMPLETE_TYPES_REQUIRED | |
| #include "libtorrent/peer_connection.hpp" | | #include "libtorrent/peer_connection.hpp" | |
| #endif | | #endif | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) | | #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) | |
| struct logger; | | struct logger; | |
| #endif | | #endif | |
| | | | |
| class piece_manager; | | class piece_manager; | |
| struct torrent_plugin; | | struct torrent_plugin; | |
| struct bitfield; | | struct bitfield; | |
|
| | | struct announce_entry; | |
| | | struct tracker_request; | |
| | | struct add_torrent_params; | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
|
| struct session_impl; | | | |
| struct piece_checker_data; | | struct piece_checker_data; | |
| } | | } | |
| | | | |
|
| | | struct web_seed_entry | |
| | | { | |
| | | std::string url; | |
| | | // http seeds are different from url seeds in the | |
| | | // protocol they use. http seeds follows the original | |
| | | // http seed spec. by John Hoffman | |
| | | enum type_t { url_seed, http_seed} type; | |
| | | | |
| | | web_seed_entry(std::string const& url_, type_t type_) | |
| | | : url(url_), type(type_) {} | |
| | | | |
| | | bool operator==(web_seed_entry const& e) const | |
| | | { return url == e.url && type == e.type; } | |
| | | | |
| | | bool operator<(web_seed_entry const& e) const | |
| | | { | |
| | | if (url < e.url) return true; | |
| | | if (url > e.url) return false; | |
| | | return type < e.type; | |
| | | } | |
| | | }; | |
| | | | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| | | | |
| // a torrent is a class that holds information | | // a torrent is a class that holds information | |
| // for a specific download. It updates itself against | | // for a specific download. It updates itself against | |
| // the tracker | | // the tracker | |
| class TORRENT_EXPORT torrent: public request_callback | | class TORRENT_EXPORT torrent: public request_callback | |
| , public boost::enable_shared_from_this<torrent> | | , public boost::enable_shared_from_this<torrent> | |
| { | | { | |
| public: | | public: | |
| | | | |
|
| torrent( | | torrent(aux::session_impl& ses, tcp::endpoint const& net_int | |
| aux::session_impl& ses | | erface | |
| , boost::intrusive_ptr<torrent_info> tf | | , int block_size, int seq, add_torrent_params const& | |
| , fs::path const& save_path | | p); | |
| , tcp::endpoint const& net_interface | | | |
| , storage_mode_t m_storage_mode | | | |
| , int block_size | | | |
| , storage_constructor_type sc | | | |
| , bool paused | | | |
| , std::vector<char>* resume_data | | | |
| , int seq | | | |
| , bool auto_managed); | | | |
| | | | |
| // used with metadata-less torrents | | | |
| // (the metadata is downloaded from the peers) | | | |
| torrent( | | | |
| aux::session_impl& ses | | | |
| , char const* tracker_url | | | |
| , sha1_hash const& info_hash | | | |
| , char const* name | | | |
| , fs::path const& save_path | | | |
| , tcp::endpoint const& net_interface | | | |
| , storage_mode_t m_storage_mode | | | |
| , int block_size | | | |
| , storage_constructor_type sc | | | |
| , bool paused | | | |
| , std::vector<char>* resume_data | | | |
| , int seq | | | |
| , bool auto_managed); | | | |
| | | | |
| ~torrent(); | | ~torrent(); | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| sha1_hash const& obfuscated_hash() const | | sha1_hash const& obfuscated_hash() const | |
| { return m_obfuscated_hash; } | | { return m_obfuscated_hash; } | |
| #endif | | #endif | |
| | | | |
| sha1_hash const& info_hash() const | | sha1_hash const& info_hash() const | |
| { return m_torrent_file->info_hash(); } | | { return m_torrent_file->info_hash(); } | |
| | | | |
| | | | |
| skipping to change at line 166 | | skipping to change at line 162 | |
| { return m_connections.find(p) != m_connections.end(); } | | { return m_connections.find(p) != m_connections.end(); } | |
| #endif | | #endif | |
| | | | |
| // this is called when the torrent has metadata. | | // this is called when the torrent has metadata. | |
| // it will initialize the storage and the piece-picker | | // it will initialize the storage and the piece-picker | |
| void init(); | | void init(); | |
| | | | |
| void on_resume_data_checked(int ret, disk_io_job const& j); | | void on_resume_data_checked(int ret, disk_io_job const& j); | |
| void on_force_recheck(int ret, disk_io_job const& j); | | void on_force_recheck(int ret, disk_io_job const& j); | |
| void on_piece_checked(int ret, disk_io_job const& j); | | void on_piece_checked(int ret, disk_io_job const& j); | |
|
| void files_checked(); | | void files_checked_lock(); | |
| | | void files_checked(aux::session_impl::mutex_t::scoped_lock c | |
| | | onst&); | |
| void start_checking(); | | void start_checking(); | |
| | | | |
| void start_announcing(); | | void start_announcing(); | |
| void stop_announcing(); | | void stop_announcing(); | |
| | | | |
|
| | | void send_upload_only(); | |
| | | | |
| | | void set_upload_mode(bool b); | |
| | | bool upload_mode() const { return m_upload_mode; } | |
| | | bool is_upload_only() const | |
| | | { return (is_finished() || upload_mode()) && !super_seeding( | |
| | | ); } | |
| | | | |
| int seed_rank(session_settings const& s) const; | | int seed_rank(session_settings const& s) const; | |
| | | | |
|
| | | enum flags_t { overwrite_existing = 1 }; | |
| | | void add_piece(int piece, char const* data, int flags = 0); | |
| | | void on_disk_write_complete(int ret, disk_io_job const& j | |
| | | , peer_request p); | |
| | | | |
| | | struct read_piece_struct | |
| | | { | |
| | | boost::shared_array<char> piece_data; | |
| | | int blocks_left; | |
| | | bool fail; | |
| | | }; | |
| | | void read_piece(int piece); | |
| | | void on_disk_read_complete(int ret, disk_io_job const& j, pe | |
| | | er_request r, read_piece_struct* rp); | |
| | | | |
| storage_mode_t storage_mode() const { return m_storage_mode;
} | | storage_mode_t storage_mode() const { return m_storage_mode;
} | |
| storage_interface* get_storage() | | storage_interface* get_storage() | |
| { | | { | |
| if (!m_owning_storage) return 0; | | if (!m_owning_storage) return 0; | |
| return m_owning_storage->get_storage_impl(); | | return m_owning_storage->get_storage_impl(); | |
| } | | } | |
| | | | |
| // this will flag the torrent as aborted. The main | | // this will flag the torrent as aborted. The main | |
| // loop in session_impl will check for this state | | // loop in session_impl will check for this state | |
| // on all torrents once every second, and take | | // on all torrents once every second, and take | |
| // the necessary actions then. | | // the necessary actions then. | |
| void abort(); | | void abort(); | |
| bool is_aborted() const { return m_abort; } | | bool is_aborted() const { return m_abort; } | |
| | | | |
| torrent_status::state_t state() const { return m_state; } | | torrent_status::state_t state() const { return m_state; } | |
| void set_state(torrent_status::state_t s); | | void set_state(torrent_status::state_t s); | |
| | | | |
|
| void clear_error(); | | | |
| | | | |
| session_settings const& settings() const; | | session_settings const& settings() const; | |
| | | | |
| aux::session_impl& session() { return m_ses; } | | aux::session_impl& session() { return m_ses; } | |
| | | | |
| void set_sequential_download(bool sd); | | void set_sequential_download(bool sd); | |
| bool is_sequential_download() const | | bool is_sequential_download() const | |
| { return m_sequential_download; } | | { return m_sequential_download; } | |
| | | | |
| void set_queue_position(int p); | | void set_queue_position(int p); | |
| int queue_position() const { return m_sequence_number; } | | int queue_position() const { return m_sequence_number; } | |
| | | | |
|
| void second_tick(stat& accumulator, float tick_interval); | | void second_tick(stat& accumulator, int tick_interval_ms); | |
| | | | |
| // debug purpose only | | | |
| void print(std::ostream& os) const; | | | |
| | | | |
| std::string name() const; | | std::string name() const; | |
| | | | |
| stat statistics() const { return m_stat; } | | stat statistics() const { return m_stat; } | |
|
| void add_stats(stat const& s) { m_stat += s; } | | void add_stats(stat const& s); | |
| size_type bytes_left() const; | | size_type bytes_left() const; | |
|
| boost::tuples::tuple<size_type, size_type> bytes_done() cons | | int block_bytes_wanted(piece_block const& p) const; | |
| t; | | void bytes_done(torrent_status& st) const; | |
| size_type quantized_bytes_done() const; | | size_type quantized_bytes_done() const; | |
| | | | |
| void ip_filter_updated() { m_policy.ip_filter_updated(); } | | void ip_filter_updated() { m_policy.ip_filter_updated(); } | |
| | | | |
|
| void set_error(std::string const& msg); | | void handle_disk_error(disk_io_job const& j, peer_connection | |
| bool has_error() const { return !m_error.empty(); } | | * c = 0); | |
| | | void clear_error(); | |
| | | void set_error(error_code const& ec, std::string const& file | |
| | | ); | |
| | | bool has_error() const { return m_error; } | |
| | | | |
| | | void flush_cache(); | |
| void pause(); | | void pause(); | |
| void resume(); | | void resume(); | |
| | | | |
| ptime started() const { return m_started; } | | ptime started() const { return m_started; } | |
| void do_pause(); | | void do_pause(); | |
| void do_resume(); | | void do_resume(); | |
| | | | |
| bool is_paused() const; | | bool is_paused() const; | |
| bool is_torrent_paused() const { return m_paused; } | | bool is_torrent_paused() const { return m_paused; } | |
| void force_recheck(); | | void force_recheck(); | |
| | | | |
| skipping to change at line 246 | | skipping to change at line 264 | |
| bool should_check_files() const; | | bool should_check_files() const; | |
| | | | |
| void delete_files(); | | void delete_files(); | |
| | | | |
| // ============ start deprecation ============= | | // ============ start deprecation ============= | |
| void filter_piece(int index, bool filter); | | void filter_piece(int index, bool filter); | |
| void filter_pieces(std::vector<bool> const& bitmask); | | void filter_pieces(std::vector<bool> const& bitmask); | |
| bool is_piece_filtered(int index) const; | | bool is_piece_filtered(int index) const; | |
| void filtered_pieces(std::vector<bool>& bitmask) const; | | void filtered_pieces(std::vector<bool>& bitmask) const; | |
| void filter_files(std::vector<bool> const& files); | | void filter_files(std::vector<bool> const& files); | |
|
| | | #if !TORRENT_NO_FPU | |
| void file_progress(std::vector<float>& fp) const; | | void file_progress(std::vector<float>& fp) const; | |
|
| | | #endif | |
| // ============ end deprecation ============= | | // ============ end deprecation ============= | |
| | | | |
| void piece_availability(std::vector<int>& avail) const; | | void piece_availability(std::vector<int>& avail) const; | |
| | | | |
| void set_piece_priority(int index, int priority); | | void set_piece_priority(int index, int priority); | |
| int piece_priority(int index) const; | | int piece_priority(int index) const; | |
| | | | |
| void prioritize_pieces(std::vector<int> const& pieces); | | void prioritize_pieces(std::vector<int> const& pieces); | |
| void piece_priorities(std::vector<int>&) const; | | void piece_priorities(std::vector<int>&) const; | |
| | | | |
| void set_file_priority(int index, int priority); | | void set_file_priority(int index, int priority); | |
| int file_priority(int index) const; | | int file_priority(int index) const; | |
| | | | |
| void prioritize_files(std::vector<int> const& files); | | void prioritize_files(std::vector<int> const& files); | |
| void file_priorities(std::vector<int>&) const; | | void file_priorities(std::vector<int>&) const; | |
| | | | |
|
| | | void set_piece_deadline(int piece, int t, int flags); | |
| void update_piece_priorities(); | | void update_piece_priorities(); | |
| | | | |
| torrent_status status() const; | | torrent_status status() const; | |
| | | | |
|
| void file_progress(std::vector<size_type>& fp) const; | | void file_progress(std::vector<size_type>& fp, int flags = 0
) const; | |
| | | | |
| void use_interface(const char* net_interface); | | void use_interface(const char* net_interface); | |
| tcp::endpoint const& get_interface() const { return m_net_in
terface; } | | tcp::endpoint const& get_interface() const { return m_net_in
terface; } | |
| | | | |
|
| void connect_to_url_seed(std::string const& url); | | void connect_to_url_seed(web_seed_entry const& url); | |
| bool connect_to_peer(policy::peer* peerinfo); | | bool connect_to_peer(policy::peer* peerinfo); | |
| | | | |
|
| void set_ratio(float ratio) | | void set_ratio(float r) | |
| { TORRENT_ASSERT(ratio >= 0.0f); m_ratio = ratio; } | | { TORRENT_ASSERT(r >= 0.0f); m_ratio = r; } | |
| | | | |
| float ratio() const | | float ratio() const | |
| { return m_ratio; } | | { return m_ratio; } | |
| | | | |
|
| | | int priority() const { return m_priority; } | |
| | | void set_priority(int prio) | |
| | | { | |
| | | TORRENT_ASSERT(prio <= 255 && prio >= 0); | |
| | | if (prio > 255) prio = 255; | |
| | | else if (prio < 0) prio = 0; | |
| | | m_priority = prio; | |
| | | } | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| void resolve_countries(bool r) | | void resolve_countries(bool r) | |
| { m_resolve_countries = r; } | | { m_resolve_countries = r; } | |
| | | | |
| bool resolving_countries() const { return m_resolve_countrie
s; } | | bool resolving_countries() const { return m_resolve_countrie
s; } | |
| #endif | | #endif | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // BANDWIDTH MANAGEMENT | | // BANDWIDTH MANAGEMENT | |
| | | | |
|
| bandwidth_limit m_bandwidth_limit[2]; | | bandwidth_channel m_bandwidth_channel[2]; | |
| | | | |
| void request_bandwidth(int channel | | | |
| , boost::intrusive_ptr<peer_connection> const& p | | | |
| , int max_block_size, int priority); | | | |
| | | | |
| void perform_bandwidth_request(int channel | | | |
| , boost::intrusive_ptr<peer_connection> const& p | | | |
| , int block_size, int priority); | | | |
| | | | |
| void expire_bandwidth(int channel, int amount); | | | |
| void assign_bandwidth(int channel, int amount, int blk); | | | |
| | | | |
| int bandwidth_throttle(int channel) const; | | int bandwidth_throttle(int channel) const; | |
| | | | |
|
| int max_assignable_bandwidth(int channel) const | | | |
| { return m_bandwidth_limit[channel].max_assignable(); } | | | |
| | | | |
| int bandwidth_queue_size(int channel) const; | | | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // PEER MANAGEMENT | | // PEER MANAGEMENT | |
| | | | |
| // add or remove a url that will be attempted for | | // add or remove a url that will be attempted for | |
| // finding the file(s) in this torrent. | | // finding the file(s) in this torrent. | |
|
| void add_url_seed(std::string const& url) | | void add_web_seed(std::string const& url, web_seed_entry::ty | |
| { m_web_seeds.insert(url); } | | pe_t type) | |
| | | { m_web_seeds.insert(web_seed_entry(url, type)); } | |
| | | | |
|
| void remove_url_seed(std::string const& url) | | void remove_web_seed(std::string const& url, web_seed_entry: | |
| { m_web_seeds.erase(url); } | | :type_t type) | |
| | | { m_web_seeds.erase(web_seed_entry(url, type)); } | |
| | | | |
|
| void retry_url_seed(std::string const& url); | | void retry_web_seed(std::string const& url, web_seed_entry::
type_t type, int retry = 0); | |
| | | | |
|
| std::set<std::string> url_seeds() const | | std::set<web_seed_entry> web_seeds() const | |
| { return m_web_seeds; } | | { return m_web_seeds; } | |
| | | | |
|
| | | std::set<std::string> web_seeds(web_seed_entry::type_t type) | |
| | | const; | |
| | | | |
| bool free_upload_slots() const | | bool free_upload_slots() const | |
| { return m_num_uploads < m_max_uploads; } | | { return m_num_uploads < m_max_uploads; } | |
| | | | |
|
| void choke_peer(peer_connection& c); | | bool choke_peer(peer_connection& c); | |
| bool unchoke_peer(peer_connection& c); | | bool unchoke_peer(peer_connection& c); | |
| | | | |
| // used by peer_connection to attach itself to a torrent | | // used by peer_connection to attach itself to a torrent | |
| // since incoming connections don't know what torrent | | // since incoming connections don't know what torrent | |
| // they're a part of until they have received an info_hash. | | // they're a part of until they have received an info_hash. | |
| // false means attach failed | | // false means attach failed | |
| bool attach_peer(peer_connection* p); | | bool attach_peer(peer_connection* p); | |
| | | | |
| // this will remove the peer and make sure all | | // this will remove the peer and make sure all | |
| // the pieces it had have their reference counter | | // the pieces it had have their reference counter | |
| | | | |
| skipping to change at line 378 | | skipping to change at line 394 | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // TRACKER MANAGEMENT | | // TRACKER MANAGEMENT | |
| | | | |
| // these are callbacks called by the tracker_connection inst
ance | | // these are callbacks called by the tracker_connection inst
ance | |
| // (either http_tracker_connection or udp_tracker_connection
) | | // (either http_tracker_connection or udp_tracker_connection
) | |
| // when this torrent got a response from its tracker request | | // when this torrent got a response from its tracker request | |
| // or when a failure occured | | // or when a failure occured | |
| virtual void tracker_response( | | virtual void tracker_response( | |
| tracker_request const& r | | tracker_request const& r | |
|
| , std::vector<peer_entry>& e, int interval | | , address const& tracker_ip | |
| | | , std::list<address> const& ip_list | |
| | | , std::vector<peer_entry>& e, int interval, int min_ | |
| | | interval | |
| , int complete, int incomplete, address const& exter
nal_ip); | | , int complete, int incomplete, address const& exter
nal_ip); | |
| virtual void tracker_request_timed_out( | | virtual void tracker_request_timed_out( | |
| tracker_request const& r); | | tracker_request const& r); | |
| virtual void tracker_request_error(tracker_request const& r | | virtual void tracker_request_error(tracker_request const& r | |
|
| , int response_code, const std::string& str); | | , int response_code, const std::string& str, int ret
ry_interval); | |
| virtual void tracker_warning(tracker_request const& req | | virtual void tracker_warning(tracker_request const& req | |
| , std::string const& msg); | | , std::string const& msg); | |
| virtual void tracker_scrape_response(tracker_request const&
req | | virtual void tracker_scrape_response(tracker_request const&
req | |
| , int complete, int incomplete, int downloaded); | | , int complete, int incomplete, int downloaded); | |
| | | | |
| // if no password and username is set | | // if no password and username is set | |
| // this will return an empty string, otherwise | | // this will return an empty string, otherwise | |
| // it will concatenate the login and password | | // it will concatenate the login and password | |
| // ready to be sent over http (but without | | // ready to be sent over http (but without | |
| // base64 encoding). | | // base64 encoding). | |
| | | | |
| skipping to change at line 405 | | skipping to change at line 423 | |
| | | | |
| // returns the absolute time when the next tracker | | // returns the absolute time when the next tracker | |
| // announce will take place. | | // announce will take place. | |
| ptime next_announce() const; | | ptime next_announce() const; | |
| | | | |
| // forcefully sets next_announce to the current time | | // forcefully sets next_announce to the current time | |
| void force_tracker_request(); | | void force_tracker_request(); | |
| void force_tracker_request(ptime); | | void force_tracker_request(ptime); | |
| void scrape_tracker(); | | void scrape_tracker(); | |
| void announce_with_tracker(tracker_request::event_t e | | void announce_with_tracker(tracker_request::event_t e | |
|
| = tracker_request::none); | | = tracker_request::none | |
| | | , address const& bind_interface = address_v4::any()) | |
| | | ; | |
| ptime const& last_scrape() const { return m_last_scrape; } | | ptime const& last_scrape() const { return m_last_scrape; } | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
| void force_dht_announce(); | | void force_dht_announce(); | |
| #endif | | #endif | |
| | | | |
| // sets the username and password that will be sent to | | // sets the username and password that will be sent to | |
| // the tracker | | // the tracker | |
| void set_tracker_login(std::string const& name, std::string
const& pw); | | void set_tracker_login(std::string const& name, std::string
const& pw); | |
| | | | |
| // the tcp::endpoint of the tracker that we managed to | | // the tcp::endpoint of the tracker that we managed to | |
| // announce ourself at the last time we tried to announce | | // announce ourself at the last time we tried to announce | |
| const tcp::endpoint& current_tracker() const; | | const tcp::endpoint& current_tracker() const; | |
| | | | |
|
| | | announce_entry* find_tracker(tracker_request const& r); | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // PIECE MANAGEMENT | | // PIECE MANAGEMENT | |
| | | | |
|
| | | void update_sparse_piece_prio(int piece, int cursor, int rev | |
| | | erse_cursor); | |
| | | | |
| | | bool super_seeding() const | |
| | | { return m_super_seeding; } | |
| | | | |
| | | void super_seeding(bool on); | |
| | | int get_piece_to_super_seed(bitfield const&); | |
| | | | |
| // returns true if we have downloaded the given piece | | // returns true if we have downloaded the given piece | |
| bool have_piece(int index) const | | bool have_piece(int index) const | |
| { | | { | |
| return has_picker()?m_picker->have_piece(index):true
; | | return has_picker()?m_picker->have_piece(index):true
; | |
| } | | } | |
| | | | |
|
| | | // called when we learn that we have a piece | |
| | | // only once per piece | |
| | | void we_have(int index); | |
| | | | |
| int num_have() const | | int num_have() const | |
| { | | { | |
| return has_picker() | | return has_picker() | |
| ?m_picker->num_have() | | ?m_picker->num_have() | |
| :m_torrent_file->num_pieces(); | | :m_torrent_file->num_pieces(); | |
| } | | } | |
| | | | |
| // when we get a have message, this is called for that piece | | // when we get a have message, this is called for that piece | |
| void peer_has(int index) | | void peer_has(int index) | |
| { | | { | |
| | | | |
| skipping to change at line 501 | | skipping to change at line 534 | |
| else | | else | |
| { | | { | |
| TORRENT_ASSERT(is_seed()); | | TORRENT_ASSERT(is_seed()); | |
| } | | } | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| int block_size() const { TORRENT_ASSERT(m_block_size > 0); r
eturn m_block_size; } | | int block_size() const { TORRENT_ASSERT(m_block_size > 0); r
eturn m_block_size; } | |
| peer_request to_req(piece_block const& p) const; | | peer_request to_req(piece_block const& p) const; | |
| | | | |
|
| void disconnect_all(); | | void disconnect_all(error_code const& ec); | |
| int disconnect_peers(int num); | | int disconnect_peers(int num); | |
| | | | |
| // this is called wheh the torrent has completed | | // this is called wheh the torrent has completed | |
| // the download. It will post an event, disconnect | | // the download. It will post an event, disconnect | |
| // all seeds and let the tracker know we're finished. | | // all seeds and let the tracker know we're finished. | |
| void completed(); | | void completed(); | |
| | | | |
| // this is the asio callback that is called when a name | | // this is the asio callback that is called when a name | |
| // lookup for a PEER is completed. | | // lookup for a PEER is completed. | |
| void on_peer_name_lookup(error_code const& e, tcp::resolver:
:iterator i | | void on_peer_name_lookup(error_code const& e, tcp::resolver:
:iterator i | |
| , peer_id pid); | | , peer_id pid); | |
| | | | |
| // this is the asio callback that is called when a name | | // this is the asio callback that is called when a name | |
| // lookup for a WEB SEED is completed. | | // lookup for a WEB SEED is completed. | |
| void on_name_lookup(error_code const& e, tcp::resolver::iter
ator i | | void on_name_lookup(error_code const& e, tcp::resolver::iter
ator i | |
|
| , std::string url, tcp::endpoint proxy); | | , web_seed_entry url, tcp::endpoint proxy); | |
| | | | |
| // this is the asio callback that is called when a name | | // this is the asio callback that is called when a name | |
| // lookup for a proxy for a web seed is completed. | | // lookup for a proxy for a web seed is completed. | |
| void on_proxy_name_lookup(error_code const& e, tcp::resolver
::iterator i | | void on_proxy_name_lookup(error_code const& e, tcp::resolver
::iterator i | |
|
| , std::string url); | | , web_seed_entry url); | |
| | | | |
| // this is called when the torrent has finished. i.e. | | // this is called when the torrent has finished. i.e. | |
| // all the pieces we have not filtered have been downloaded. | | // all the pieces we have not filtered have been downloaded. | |
| // If no pieces are filtered, this is called first and then | | // If no pieces are filtered, this is called first and then | |
| // completed() is called immediately after it. | | // completed() is called immediately after it. | |
| void finished(); | | void finished(); | |
| | | | |
| // This is the opposite of finished. It is called if we used | | // This is the opposite of finished. It is called if we used | |
| // to be finished but enabled some files for download so tha
t | | // to be finished but enabled some files for download so tha
t | |
| // we wasn't finished anymore. | | // we wasn't finished anymore. | |
| | | | |
| skipping to change at line 597 | | skipping to change at line 630 | |
| } | | } | |
| policy& get_policy() { return m_policy; } | | policy& get_policy() { return m_policy; } | |
| piece_manager& filesystem(); | | piece_manager& filesystem(); | |
| torrent_info const& torrent_file() const | | torrent_info const& torrent_file() const | |
| { return *m_torrent_file; } | | { return *m_torrent_file; } | |
| | | | |
| std::vector<announce_entry> const& trackers() const | | std::vector<announce_entry> const& trackers() const | |
| { return m_trackers; } | | { return m_trackers; } | |
| | | | |
| void replace_trackers(std::vector<announce_entry> const& url
s); | | void replace_trackers(std::vector<announce_entry> const& url
s); | |
|
| | | void add_tracker(announce_entry const& url); | |
| | | | |
| torrent_handle get_handle(); | | torrent_handle get_handle(); | |
| | | | |
| void write_resume_data(entry& rd) const; | | void write_resume_data(entry& rd) const; | |
| void read_resume_data(lazy_entry const& rd); | | void read_resume_data(lazy_entry const& rd); | |
| | | | |
| // LOGGING | | // LOGGING | |
| #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | | #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined T
ORRENT_ERROR_LOGGING | |
| virtual void debug_log(const std::string& line); | | virtual void debug_log(const std::string& line); | |
| #endif | | #endif | |
| | | | |
| // DEBUG | | // DEBUG | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| void check_invariant() const; | | void check_invariant() const; | |
| #endif | | #endif | |
| | | | |
| // -------------------------------------------- | | // -------------------------------------------- | |
| // RESOURCE MANAGEMENT | | // RESOURCE MANAGEMENT | |
| | | | |
|
| | | void add_free_upload(int diff) { m_available_free_upload += | |
| | | diff; } | |
| | | | |
| void set_peer_upload_limit(tcp::endpoint ip, int limit); | | void set_peer_upload_limit(tcp::endpoint ip, int limit); | |
| void set_peer_download_limit(tcp::endpoint ip, int limit); | | void set_peer_download_limit(tcp::endpoint ip, int limit); | |
| | | | |
| void set_upload_limit(int limit); | | void set_upload_limit(int limit); | |
| int upload_limit() const; | | int upload_limit() const; | |
| void set_download_limit(int limit); | | void set_download_limit(int limit); | |
| int download_limit() const; | | int download_limit() const; | |
| | | | |
| void set_max_uploads(int limit); | | void set_max_uploads(int limit); | |
| int max_uploads() const { return m_max_uploads; } | | int max_uploads() const { return m_max_uploads; } | |
| | | | |
| skipping to change at line 650 | | skipping to change at line 686 | |
| bool valid_metadata() const | | bool valid_metadata() const | |
| { return m_torrent_file->is_valid(); } | | { return m_torrent_file->is_valid(); } | |
| bool are_files_checked() const | | bool are_files_checked() const | |
| { return m_files_checked; } | | { return m_files_checked; } | |
| | | | |
| // parses the info section from the given | | // parses the info section from the given | |
| // bencoded tree and moves the torrent | | // bencoded tree and moves the torrent | |
| // to the checker thread for initial checking | | // to the checker thread for initial checking | |
| // of the storage. | | // of the storage. | |
| // a return value of false indicates an error | | // a return value of false indicates an error | |
|
| bool set_metadata(lazy_entry const& metadata, std::string& e
rror); | | bool set_metadata(char const* metadata_buf, int metadata_siz
e); | |
| | | | |
| int sequence_number() const { return m_sequence_number; } | | int sequence_number() const { return m_sequence_number; } | |
| | | | |
|
| | | bool seed_mode() const { return m_seed_mode; } | |
| | | void leave_seed_mode(bool seed) | |
| | | { | |
| | | if (!m_seed_mode) return; | |
| | | m_seed_mode = false; | |
| | | // seed is false if we turned out not | |
| | | // to be a seed after all | |
| | | if (!seed) force_recheck(); | |
| | | m_num_verified = 0; | |
| | | m_verified.free(); | |
| | | } | |
| | | bool all_verified() const | |
| | | { return m_num_verified == m_torrent_file->num_pieces(); } | |
| | | bool verified_piece(int piece) const | |
| | | { | |
| | | TORRENT_ASSERT(piece < int(m_verified.size())); | |
| | | TORRENT_ASSERT(piece >= 0); | |
| | | return m_verified.get_bit(piece); | |
| | | } | |
| | | void verified(int piece) | |
| | | { | |
| | | TORRENT_ASSERT(piece < int(m_verified.size())); | |
| | | TORRENT_ASSERT(piece >= 0); | |
| | | TORRENT_ASSERT(m_verified.get_bit(piece) == false); | |
| | | ++m_num_verified; | |
| | | m_verified.set_bit(piece); | |
| | | } | |
| | | | |
| | | bool add_merkle_nodes(std::map<int, sha1_hash> const& n, int | |
| | | piece); | |
| | | | |
| | | // this is called once periodically for torrents | |
| | | // that are not private | |
| | | void lsd_announce(); | |
| | | | |
| private: | | private: | |
| | | | |
| void on_files_deleted(int ret, disk_io_job const& j); | | void on_files_deleted(int ret, disk_io_job const& j); | |
| void on_files_released(int ret, disk_io_job const& j); | | void on_files_released(int ret, disk_io_job const& j); | |
| void on_torrent_aborted(int ret, disk_io_job const& j); | | void on_torrent_aborted(int ret, disk_io_job const& j); | |
| void on_torrent_paused(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); | | void on_storage_moved(int ret, disk_io_job const& j); | |
| void on_save_resume_data(int ret, disk_io_job const& j); | | void on_save_resume_data(int ret, disk_io_job const& j); | |
| void on_file_renamed(int ret, disk_io_job const& j); | | void on_file_renamed(int ret, disk_io_job const& j); | |
|
| | | void on_cache_flushed(int ret, disk_io_job const& j); | |
| | | | |
| void on_piece_verified(int ret, disk_io_job const& j | | void on_piece_verified(int ret, disk_io_job const& j | |
| , boost::function<void(int)> f); | | , boost::function<void(int)> f); | |
| | | | |
|
| void try_next_tracker(tracker_request const& req); | | | |
| int prioritize_tracker(int tracker_index); | | int prioritize_tracker(int tracker_index); | |
|
| | | int deprioritize_tracker(int tracker_index); | |
| | | | |
| void on_country_lookup(error_code const& error, tcp::resolve
r::iterator i | | void on_country_lookup(error_code const& error, tcp::resolve
r::iterator i | |
| , boost::intrusive_ptr<peer_connection> p) const; | | , boost::intrusive_ptr<peer_connection> p) const; | |
| bool request_bandwidth_from_session(int channel) const; | | bool request_bandwidth_from_session(int channel) const; | |
| | | | |
| void update_peer_interest(bool was_finished); | | void update_peer_interest(bool was_finished); | |
|
| | | void prioritize_udp_trackers(); | |
| | | | |
| void queue_torrent_check(); | | void queue_torrent_check(); | |
| void dequeue_torrent_check(); | | void dequeue_torrent_check(); | |
| | | | |
| policy m_policy; | | policy m_policy; | |
| | | | |
| // total time we've been available on this torrent | | // total time we've been available on this torrent | |
| // does not count when the torrent is stopped or paused | | // does not count when the torrent is stopped or paused | |
| time_duration m_active_time; | | time_duration m_active_time; | |
| | | | |
|
| | | // total time we've been finished with this torrent | |
| | | // does not count when the torrent is stopped or paused | |
| | | time_duration m_finished_time; | |
| | | | |
| // total time we've been available as a seed on this torrent | | // total time we've been available as a seed on this torrent | |
| // does not count when the torrent is stopped or paused | | // does not count when the torrent is stopped or paused | |
| time_duration m_seeding_time; | | time_duration m_seeding_time; | |
| | | | |
| // all time totals of uploaded and downloaded payload | | // all time totals of uploaded and downloaded payload | |
| // stored in resume data | | // stored in resume data | |
| size_type m_total_uploaded; | | size_type m_total_uploaded; | |
| size_type m_total_downloaded; | | size_type m_total_downloaded; | |
| | | | |
| // if this torrent is running, this was the time | | // if this torrent is running, this was the time | |
| // when it was started. This is used to have a | | // when it was started. This is used to have a | |
| // bias towards keeping seeding torrents that | | // bias towards keeping seeding torrents that | |
| // recently was started, to avoid oscillation | | // recently was started, to avoid oscillation | |
| ptime m_started; | | ptime m_started; | |
| | | | |
| // the last time we initiated a scrape request to | | // the last time we initiated a scrape request to | |
| // one of the trackers in this torrent | | // one of the trackers in this torrent | |
| ptime m_last_scrape; | | ptime m_last_scrape; | |
| | | | |
|
| | | // the time when we switched to upload mode | |
| | | ptime m_upload_mode_time; | |
| | | | |
| boost::intrusive_ptr<torrent_info> m_torrent_file; | | boost::intrusive_ptr<torrent_info> m_torrent_file; | |
| | | | |
| void parse_response(const entry& e, std::vector<peer_entry>&
peer_list); | | void parse_response(const entry& e, std::vector<peer_entry>&
peer_list); | |
| | | | |
| // if this pointer is 0, the torrent is in | | // if this pointer is 0, the torrent is in | |
| // a state where the metadata hasn't been | | // a state where the metadata hasn't been | |
| // received yet. | | // received yet. | |
| // the piece_manager keeps the torrent object | | // the piece_manager keeps the torrent object | |
| // alive by holding a shared_ptr to it and | | // alive by holding a shared_ptr to it and | |
| // the torrent keeps the piece manager alive | | // the torrent keeps the piece manager alive | |
| | | | |
| skipping to change at line 732 | | skipping to change at line 812 | |
| // torrent, so the torrent cannot destruct | | // torrent, so the torrent cannot destruct | |
| // before the piece_manager. | | // before the piece_manager. | |
| boost::intrusive_ptr<piece_manager> m_owning_storage; | | boost::intrusive_ptr<piece_manager> m_owning_storage; | |
| | | | |
| // this is a weak (non owninig) pointer to | | // this is a weak (non owninig) pointer to | |
| // the piece_manager. This is used after the torrent | | // the piece_manager. This is used after the torrent | |
| // has been aborted, and it can no longer own | | // has been aborted, and it can no longer own | |
| // the object. | | // the object. | |
| piece_manager* m_storage; | | piece_manager* m_storage; | |
| | | | |
|
| // the time of next tracker announce | | | |
| ptime m_next_tracker_announce; | | | |
| | | | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| public: | | public: | |
| #endif | | #endif | |
| std::set<peer_connection*> m_connections; | | std::set<peer_connection*> m_connections; | |
| #ifdef TORRENT_DEBUG | | #ifdef TORRENT_DEBUG | |
| private: | | private: | |
| #endif | | #endif | |
| | | | |
| // The list of web seeds in this torrent. Seeds | | // The list of web seeds in this torrent. Seeds | |
| // with fatal errors are removed from the set | | // with fatal errors are removed from the set | |
|
| std::set<std::string> m_web_seeds; | | std::set<web_seed_entry> m_web_seeds; | |
| | | | |
| // a list of web seeds that have failed and are | | // a list of web seeds that have failed and are | |
| // waiting to be retried | | // waiting to be retried | |
|
| std::map<std::string, ptime> m_web_seeds_next_retry; | | std::map<web_seed_entry, ptime> m_web_seeds_next_retry; | |
| | | | |
| // urls of the web seeds that we are currently | | // urls of the web seeds that we are currently | |
| // resolving the address for | | // resolving the address for | |
|
| std::set<std::string> m_resolving_web_seeds; | | std::set<web_seed_entry> m_resolving_web_seeds; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| typedef std::list<boost::shared_ptr<torrent_plugin> > extens
ion_list_t; | | typedef std::list<boost::shared_ptr<torrent_plugin> > extens
ion_list_t; | |
| extension_list_t m_extensions; | | extension_list_t m_extensions; | |
| #endif | | #endif | |
| | | | |
| // used to resolve the names of web seeds | | // used to resolve the names of web seeds | |
| mutable tcp::resolver m_host_resolver; | | mutable tcp::resolver m_host_resolver; | |
| | | | |
|
| | | #ifndef TORRENT_DISABLE_DHT | |
| // this announce timer is used both | | // this announce timer is used both | |
| // by Local service discovery and | | // by Local service discovery and | |
| // by the DHT. | | // by the DHT. | |
|
| deadline_timer m_lsd_announce_timer; | | deadline_timer m_dht_announce_timer; | |
| | | #endif | |
| | | | |
| // used for tracker announces | | // used for tracker announces | |
| deadline_timer m_tracker_timer; | | deadline_timer m_tracker_timer; | |
| | | | |
|
| void restart_tracker_timer(ptime announce_at); | | void update_tracker_timer(); | |
| | | | |
| static void on_tracker_announce_disp(boost::weak_ptr<torrent
> p | | static void on_tracker_announce_disp(boost::weak_ptr<torrent
> p | |
| , error_code const& e); | | , error_code const& e); | |
| | | | |
| void on_tracker_announce(); | | void on_tracker_announce(); | |
| | | | |
|
| static void on_lsd_announce_disp(boost::weak_ptr<torrent> p | | void dht_announce(); | |
| , error_code const& e); | | | |
| | | | |
| // this is called once every 5 minutes for torrents | | | |
| // that are not private | | | |
| void on_lsd_announce(); | | | |
| | | | |
| #ifndef TORRENT_DISABLE_DHT | | #ifndef TORRENT_DISABLE_DHT | |
|
| static void on_dht_announce_post(boost::weak_ptr<libtorrent: | | | |
| :torrent> t | | | |
| , std::vector<tcp::endpoint> const& peers); | | | |
| static void on_dht_announce_response_disp(boost::weak_ptr<to
rrent> t | | static void on_dht_announce_response_disp(boost::weak_ptr<to
rrent> t | |
| , std::vector<tcp::endpoint> const& peers); | | , std::vector<tcp::endpoint> const& peers); | |
| void on_dht_announce_response(std::vector<tcp::endpoint> con
st& peers); | | void on_dht_announce_response(std::vector<tcp::endpoint> con
st& peers); | |
| bool should_announce_dht() const; | | bool should_announce_dht() const; | |
|
| | | void on_dht_announce(error_code const& e); | |
| | | | |
| // the time when the DHT was last announced of our | | // the time when the DHT was last announced of our | |
| // presence on this torrent | | // presence on this torrent | |
| ptime m_last_dht_announce; | | ptime m_last_dht_announce; | |
| #endif | | #endif | |
| | | | |
| // this is the upload and download statistics for the whole
torrent. | | // this is the upload and download statistics for the whole
torrent. | |
| // it's updated from all its peers once every second. | | // it's updated from all its peers once every second. | |
| libtorrent::stat m_stat; | | libtorrent::stat m_stat; | |
| | | | |
| // ----------------------------- | | // ----------------------------- | |
| | | | |
| // a back reference to the session | | // a back reference to the session | |
| // this torrent belongs to. | | // this torrent belongs to. | |
| aux::session_impl& m_ses; | | aux::session_impl& m_ses; | |
| | | | |
| std::vector<boost::uint8_t> m_file_priority; | | std::vector<boost::uint8_t> m_file_priority; | |
| | | | |
|
| boost::scoped_ptr<piece_picker> m_picker; | | // this vector contains the number of bytes completely | |
| | | // downloaded (as in passed-hash-check) in each file. | |
| | | // this lets us trigger on individual files completing | |
| | | std::vector<size_type> m_file_progress; | |
| | | | |
|
| // the queue of peer_connections that want more bandwidth | | boost::scoped_ptr<piece_picker> m_picker; | |
| typedef std::deque<bw_queue_entry<peer_connection, torrent> | | | |
| > queue_t; | | | |
| queue_t m_bandwidth_queue[2]; | | | |
| | | | |
| std::vector<announce_entry> m_trackers; | | std::vector<announce_entry> m_trackers; | |
| // this is an index into m_trackers | | // this is an index into m_trackers | |
| | | | |
|
| | | struct time_critical_piece | |
| | | { | |
| | | // when this piece was first requested | |
| | | ptime first_requested; | |
| | | // when this piece was last requested | |
| | | ptime last_requested; | |
| | | // by what time we want this piece | |
| | | ptime deadline; | |
| | | // 1 = send alert with piece data when available | |
| | | int flags; | |
| | | // how many peers it's been requested from | |
| | | int peers; | |
| | | // the piece index | |
| | | int piece; | |
| | | bool operator<(time_critical_piece const& rhs) const | |
| | | { return deadline < rhs.deadline; } | |
| | | }; | |
| | | | |
| | | void remove_time_critical_piece(int piece, bool finished = f | |
| | | alse); | |
| | | void remove_time_critical_pieces(std::vector<int> const& pri | |
| | | ority); | |
| | | void request_time_critical_pieces(); | |
| | | | |
| | | // this list is sorted by time_critical_piece::deadline | |
| | | std::list<time_critical_piece> m_time_critical_pieces; | |
| | | | |
| | | // the average time it takes to download one time critical p | |
| | | iece | |
| | | time_duration m_average_piece_time; | |
| | | // the average piece download time deviation | |
| | | time_duration m_piece_time_deviation; | |
| | | | |
| // the number of bytes that has been | | // the number of bytes that has been | |
| // downloaded that failed the hash-test | | // downloaded that failed the hash-test | |
| size_type m_total_failed_bytes; | | size_type m_total_failed_bytes; | |
| size_type m_total_redundant_bytes; | | size_type m_total_redundant_bytes; | |
| | | | |
|
| | | // the number of bytes of padding files | |
| | | int m_padding; | |
| | | | |
| std::string m_username; | | std::string m_username; | |
| std::string m_password; | | std::string m_password; | |
| | | | |
| // the network interface all outgoing connections | | // the network interface all outgoing connections | |
| // are opened through | | // are opened through | |
| tcp::endpoint m_net_interface; | | tcp::endpoint m_net_interface; | |
| | | | |
| fs::path m_save_path; | | fs::path m_save_path; | |
| | | | |
|
| | | // each bit represents a piece. a set bit means | |
| | | // the piece has had its hash verified. This | |
| | | // is only used in seed mode (when m_seed_mode | |
| | | // is true) | |
| | | bitfield m_verified; | |
| | | // m_num_verified = m_verified.count() | |
| | | int m_num_verified; | |
| | | | |
| | | // free download we have got that hasn't | |
| | | // been distributed yet. | |
| | | size_type m_available_free_upload; | |
| | | | |
| // determines the storage state for this torrent. | | // determines the storage state for this torrent. | |
| storage_mode_t m_storage_mode; | | storage_mode_t m_storage_mode; | |
| | | | |
|
| // the state of this torrent (queued, checking, downloading) | | // the state of this torrent (queued, checking, downloading,
etc.) | |
| torrent_status::state_t m_state; | | torrent_status::state_t m_state; | |
| | | | |
|
| // if there's an error on this torrent, this is the | | // set if there's an error on this torrent | |
| // error message | | error_code m_error; | |
| std::string m_error; | | // if the error ocurred on a file, this is the file | |
| | | std::string m_error_file; | |
| | | | |
| // used if there is any resume data | | // used if there is any resume data | |
| std::vector<char> m_resume_data; | | std::vector<char> m_resume_data; | |
| lazy_entry m_resume_entry; | | lazy_entry m_resume_entry; | |
| | | | |
| // if the torrent is started without metadata, it may | | // if the torrent is started without metadata, it may | |
| // still be given a name until the metadata is received | | // still be given a name until the metadata is received | |
| // once the metadata is received this field will no | | // once the metadata is received this field will no | |
| // longer be used and will be reset | | // longer be used and will be reset | |
| boost::scoped_ptr<std::string> m_name; | | boost::scoped_ptr<std::string> m_name; | |
| | | | |
| #ifndef TORRENT_DISABLE_ENCRYPTION | | #ifndef TORRENT_DISABLE_ENCRYPTION | |
| // this is SHA1("req2" + info-hash), used for | | // this is SHA1("req2" + info-hash), used for | |
| // encrypted hand shakes | | // encrypted hand shakes | |
| sha1_hash m_obfuscated_hash; | | sha1_hash m_obfuscated_hash; | |
| #endif | | #endif | |
| session_settings const& m_settings; | | session_settings const& m_settings; | |
| | | | |
| storage_constructor_type m_storage_constructor; | | storage_constructor_type m_storage_constructor; | |
| | | | |
|
| float m_progress; | | int m_progress_ppm; | |
| | | | |
| // the upload/download ratio that each peer | | // the upload/download ratio that each peer | |
| // tries to maintain. | | // tries to maintain. | |
| // 0 is infinite | | // 0 is infinite | |
| float m_ratio; | | float m_ratio; | |
| | | | |
| // the maximum number of uploads for this torrent | | // the maximum number of uploads for this torrent | |
| int m_max_uploads; | | int m_max_uploads; | |
| | | | |
| // the number of unchoked peers in this torrent | | // the number of unchoked peers in this torrent | |
| | | | |
| skipping to change at line 911 | | skipping to change at line 1031 | |
| // The quanta assigned to each torrent depends on the torren
ts | | // The quanta assigned to each torrent depends on the torren
ts | |
| // priority, whether it's seed and the number of connected | | // priority, whether it's seed and the number of connected | |
| // peers it has. This has the effect that some torrents | | // peers it has. This has the effect that some torrents | |
| // will have more connection attempts than other. Each | | // will have more connection attempts than other. Each | |
| // connection attempt costs 100 points from the deficit | | // connection attempt costs 100 points from the deficit | |
| // counter. points are deducted in try_connect_peer and | | // counter. points are deducted in try_connect_peer and | |
| // increased in give_connect_points. Outside of the | | // increased in give_connect_points. Outside of the | |
| // torrent object, these points are called connect_points. | | // torrent object, these points are called connect_points. | |
| int m_deficit_counter; | | int m_deficit_counter; | |
| | | | |
|
| // the number number of seconds between requests | | | |
| // from the tracker | | | |
| boost::int16_t m_duration; | | | |
| | | | |
| // the sequence number for this torrent, this is a | | // the sequence number for this torrent, this is a | |
| // monotonically increasing number for each added torrent | | // monotonically increasing number for each added torrent | |
| boost::int16_t m_sequence_number; | | boost::int16_t m_sequence_number; | |
| | | | |
| // the index to the last tracker that worked | | // the index to the last tracker that worked | |
| boost::int8_t m_last_working_tracker; | | boost::int8_t m_last_working_tracker; | |
| | | | |
|
| // the tracker that is currently (or was last) | | | |
| // tried | | | |
| boost::int8_t m_currently_trying_tracker; | | | |
| | | | |
| // the number of connection attempts that has | | // the number of connection attempts that has | |
| // failed in a row, this is currently used to | | // failed in a row, this is currently used to | |
| // determine the timeout until next try. | | // determine the timeout until next try. | |
| boost::int8_t m_failed_trackers; | | boost::int8_t m_failed_trackers; | |
| | | | |
| // this is a counter that is decreased every | | // this is a counter that is decreased every | |
| // second, and when it reaches 0, the policy::pulse() | | // second, and when it reaches 0, the policy::pulse() | |
| // is called and the time scaler is reset to 10. | | // is called and the time scaler is reset to 10. | |
| boost::int8_t m_time_scaler; | | boost::int8_t m_time_scaler; | |
| | | | |
|
| | | // this is the priority of the torrent. The higher | |
| | | // the value is, the more bandwidth is assigned to | |
| | | // the torrent's peers | |
| | | boost::uint8_t m_priority; | |
| | | | |
| // is set to true when the torrent has | | // is set to true when the torrent has | |
| // been aborted. | | // been aborted. | |
| bool m_abort:1; | | bool m_abort:1; | |
| | | | |
| // is true if this torrent has been paused | | // is true if this torrent has been paused | |
| bool m_paused:1; | | bool m_paused:1; | |
| | | | |
|
| | | // set to true when this torrent may not download anything | |
| | | bool m_upload_mode:1; | |
| | | | |
| // if this is true, libtorrent may pause and resume | | // if this is true, libtorrent may pause and resume | |
| // this torrent depending on queuing rules. Torrents | | // this torrent depending on queuing rules. Torrents | |
| // started with auto_managed flag set may be added in | | // started with auto_managed flag set may be added in | |
| // a paused state in case there are no available | | // a paused state in case there are no available | |
| // slots. | | // slots. | |
| bool m_auto_managed:1; | | bool m_auto_managed:1; | |
| | | | |
| #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | | #ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES | |
| // this is true while there is a country | | // this is true while there is a country | |
| // resolution in progress. To avoid flodding | | // resolution in progress. To avoid flodding | |
| | | | |
| skipping to change at line 983 | | skipping to change at line 1103 | |
| // of this torrent hasn't been initialized. If we | | // of this torrent hasn't been initialized. If we | |
| // have metadata from the start, connections are | | // have metadata from the start, connections are | |
| // initialized immediately, if we didn't have metadata, | | // initialized immediately, if we didn't have metadata, | |
| // they are initialized right after files_checked(). | | // they are initialized right after files_checked(). | |
| // valid_resume_data() will return false as long as | | // valid_resume_data() will return false as long as | |
| // the connections aren't initialized, to avoid | | // the connections aren't initialized, to avoid | |
| // them from altering the piece-picker before it | | // them from altering the piece-picker before it | |
| // has been initialized with files_checked(). | | // has been initialized with files_checked(). | |
| bool m_connections_initialized:1; | | bool m_connections_initialized:1; | |
| | | | |
|
| | | // if this is true, we're currently super seeding this | |
| | | // torrent. | |
| | | bool m_super_seeding:1; | |
| | | | |
| // is set to true every time there is an incoming | | // is set to true every time there is an incoming | |
| // connection to this torrent | | // connection to this torrent | |
| bool m_has_incoming:1; | | bool m_has_incoming:1; | |
| | | | |
| // this is set to true when the files are checked | | // this is set to true when the files are checked | |
| // before the files are checked, we don't try to | | // before the files are checked, we don't try to | |
| // connect to peers | | // connect to peers | |
| bool m_files_checked:1; | | bool m_files_checked:1; | |
| | | | |
| // this is true if the torrent has been added to | | // this is true if the torrent has been added to | |
| // checking queue in the session | | // checking queue in the session | |
| bool m_queued_for_checking:1; | | bool m_queued_for_checking:1; | |
| | | | |
| // this is true while tracker announcing is enabled | | // this is true while tracker announcing is enabled | |
| // is is disabled while paused and checking files | | // is is disabled while paused and checking files | |
| bool m_announcing:1; | | bool m_announcing:1; | |
| | | | |
|
| // this is true if event start has been sent to the tracker | | // this is true while the tracker deadline timer | |
| bool m_start_sent:1; | | // is in use. i.e. one or more trackers are waiting | |
| | | // for a reannounce | |
| // this is true if event completed has been sent to the trac | | bool m_waiting_tracker:1; | |
| ker | | | |
| bool m_complete_sent:1; | | | |
| }; | | | |
| | | | |
| inline ptime torrent::next_announce() const | | | |
| { | | | |
| return m_next_tracker_announce; | | | |
| } | | | |
| | | | |
| inline void torrent::force_tracker_request() | | | |
| { | | | |
| if (!is_paused()) announce_with_tracker(); | | | |
| } | | | |
| | | | |
| inline void torrent::force_tracker_request(ptime t) | | | |
| { | | | |
| if (!is_paused()) restart_tracker_timer(t); | | | |
| } | | | |
| | | | |
|
| inline void torrent::set_tracker_login( | | // this means we haven't verified the file content | |
| std::string const& name | | // of the files we're seeding. the m_verified bitfield | |
| , std::string const& pw) | | // indicates which pieces have been verified and which | |
| { | | // haven't | |
| m_username = name; | | bool m_seed_mode:1; | |
| m_password = pw; | | | |
| } | | | |
| | | | |
|
| | | // this is set when we don't want to load seed_mode, | |
| | | // paused or auto_managed from the resume data | |
| | | bool m_override_resume_data:1; | |
| | | }; | |
| } | | } | |
| | | | |
| #endif // TORRENT_TORRENT_HPP_INCLUDED | | #endif // TORRENT_TORRENT_HPP_INCLUDED | |
| | | | |
End of changes. 74 change blocks. |
| 144 lines changed or deleted | | 267 lines changed or added | |
|
| torrent_handle.hpp | | torrent_handle.hpp | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 69 | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| | | | |
| namespace aux | | namespace aux | |
| { | | { | |
| struct session_impl; | | struct session_impl; | |
| struct checker_impl; | | struct checker_impl; | |
| } | | } | |
| | | | |
| struct torrent_plugin; | | struct torrent_plugin; | |
| | | | |
|
| struct TORRENT_EXPORT duplicate_torrent: std::exception | | #ifndef BOOST_NO_EXCEPTIONS | |
| { | | // for compatibility with 0.14 | |
| virtual const char* what() const throw() | | typedef libtorrent_exception duplicate_torrent; | |
| { return "torrent already exists in session"; } | | typedef libtorrent_exception invalid_handle; | |
| }; | | void throw_invalid_handle(); | |
| | | #endif | |
| struct TORRENT_EXPORT invalid_handle: std::exception | | | |
| { | | | |
| virtual const char* what() const throw() | | | |
| { return "invalid torrent handle used"; } | | | |
| }; | | | |
| | | | |
| struct TORRENT_EXPORT torrent_status | | struct TORRENT_EXPORT torrent_status | |
| { | | { | |
| torrent_status() | | torrent_status() | |
| : state(checking_resume_data) | | : state(checking_resume_data) | |
| , paused(false) | | , paused(false) | |
| , progress(0.f) | | , progress(0.f) | |
|
| | | , progress_ppm(0) | |
| , total_download(0) | | , total_download(0) | |
| , total_upload(0) | | , total_upload(0) | |
| , total_payload_download(0) | | , total_payload_download(0) | |
| , total_payload_upload(0) | | , total_payload_upload(0) | |
| , total_failed_bytes(0) | | , total_failed_bytes(0) | |
| , total_redundant_bytes(0) | | , total_redundant_bytes(0) | |
| , download_rate(0) | | , download_rate(0) | |
| , upload_rate(0) | | , upload_rate(0) | |
| , download_payload_rate(0) | | , download_payload_rate(0) | |
| , upload_payload_rate(0) | | , upload_payload_rate(0) | |
| | | | |
| skipping to change at line 119 | | skipping to change at line 115 | |
| , num_uploads(0) | | , num_uploads(0) | |
| , num_connections(0) | | , num_connections(0) | |
| , uploads_limit(0) | | , uploads_limit(0) | |
| , connections_limit(0) | | , connections_limit(0) | |
| , storage_mode(storage_mode_sparse) | | , storage_mode(storage_mode_sparse) | |
| , up_bandwidth_queue(0) | | , up_bandwidth_queue(0) | |
| , down_bandwidth_queue(0) | | , down_bandwidth_queue(0) | |
| , all_time_upload(0) | | , all_time_upload(0) | |
| , all_time_download(0) | | , all_time_download(0) | |
| , active_time(0) | | , active_time(0) | |
|
| | | , finished_time(0) | |
| , seeding_time(0) | | , seeding_time(0) | |
| , seed_rank(0) | | , seed_rank(0) | |
| , last_scrape(0) | | , last_scrape(0) | |
| , has_incoming(false) | | , has_incoming(false) | |
|
| | | , sparse_regions(0) | |
| | | , seed_mode(false) | |
| | | , upload_mode(false) | |
| | | , priority(0) | |
| {} | | {} | |
| | | | |
| enum state_t | | enum state_t | |
| { | | { | |
| queued_for_checking, | | queued_for_checking, | |
| checking_files, | | checking_files, | |
| downloading_metadata, | | downloading_metadata, | |
| downloading, | | downloading, | |
| finished, | | finished, | |
| seeding, | | seeding, | |
| allocating, | | allocating, | |
| checking_resume_data | | checking_resume_data | |
| }; | | }; | |
| | | | |
| state_t state; | | state_t state; | |
| bool paused; | | bool paused; | |
| float progress; | | float progress; | |
|
| | | // progress parts per million (progress * 1000000) | |
| | | // when disabling floating point operations, this is | |
| | | // the only option to query progress | |
| | | int progress_ppm; | |
| std::string error; | | std::string error; | |
| | | | |
| boost::posix_time::time_duration next_announce; | | boost::posix_time::time_duration next_announce; | |
| boost::posix_time::time_duration announce_interval; | | boost::posix_time::time_duration announce_interval; | |
| | | | |
| std::string current_tracker; | | std::string current_tracker; | |
| | | | |
| // transferred this session! | | // transferred this session! | |
| // total, payload plus protocol | | // total, payload plus protocol | |
| size_type total_download; | | size_type total_download; | |
| | | | |
| skipping to change at line 166 | | skipping to change at line 171 | |
| // the amount of payload bytes that | | // the amount of payload bytes that | |
| // has failed their hash test | | // has failed their hash test | |
| size_type total_failed_bytes; | | size_type total_failed_bytes; | |
| | | | |
| // the number of payload bytes that | | // the number of payload bytes that | |
| // has been received redundantly. | | // has been received redundantly. | |
| size_type total_redundant_bytes; | | size_type total_redundant_bytes; | |
| | | | |
| // current transfer rate | | // current transfer rate | |
| // payload plus protocol | | // payload plus protocol | |
|
| float download_rate; | | int download_rate; | |
| float upload_rate; | | int upload_rate; | |
| | | | |
| // the rate of payload that is | | // the rate of payload that is | |
| // sent and received | | // sent and received | |
|
| float download_payload_rate; | | int download_payload_rate; | |
| float upload_payload_rate; | | int upload_payload_rate; | |
| | | | |
| // the number of peers this torrent is connected to | | // the number of peers this torrent is connected to | |
| // that are seeding. | | // that are seeding. | |
| int num_seeds; | | int num_seeds; | |
| | | | |
| // the number of peers this torrent | | // the number of peers this torrent | |
| // is connected to (including seeds). | | // is connected to (including seeds). | |
| int num_peers; | | int num_peers; | |
| | | | |
| // if the tracker sends scrape info in its | | // if the tracker sends scrape info in its | |
| | | | |
| skipping to change at line 233 | | skipping to change at line 238 | |
| size_type total_wanted; | | size_type total_wanted; | |
| | | | |
| // the number of distributed copies of the file. | | // the number of distributed copies of the file. | |
| // note that one copy may be spread out among many peers. | | // note that one copy may be spread out among many peers. | |
| // | | // | |
| // the integer part tells how many copies | | // the integer part tells how many copies | |
| // there are of the rarest piece(s) | | // there are of the rarest piece(s) | |
| // | | // | |
| // the fractional part tells the fraction of pieces that | | // the fractional part tells the fraction of pieces that | |
| // have more copies than the rarest piece(s). | | // have more copies than the rarest piece(s). | |
|
| | | | |
| | | // the number of full distributed copies (i.e. the number | |
| | | // of peers that have the rarest piece) | |
| | | int distributed_full_copies; | |
| | | | |
| | | // the fraction of pieces that more peers has than the | |
| | | // rarest pieces. This indicates how close the swarm is | |
| | | // to have one more full distributed copy | |
| | | int distributed_fraction; | |
| | | | |
| float distributed_copies; | | float distributed_copies; | |
| | | | |
| // the block size that is used in this torrent. i.e. | | // the block size that is used in this torrent. i.e. | |
| // the number of bytes each piece request asks for | | // the number of bytes each piece request asks for | |
| // and each bit in the download queue bitfield represents | | // and each bit in the download queue bitfield represents | |
| int block_size; | | int block_size; | |
| | | | |
| int num_uploads; | | int num_uploads; | |
| int num_connections; | | int num_connections; | |
| int uploads_limit; | | int uploads_limit; | |
| | | | |
| skipping to change at line 261 | | skipping to change at line 276 | |
| | | | |
| // number of bytes downloaded since torrent was started | | // number of bytes downloaded since torrent was started | |
| // saved and restored from resume data | | // saved and restored from resume data | |
| size_type all_time_upload; | | size_type all_time_upload; | |
| size_type all_time_download; | | size_type all_time_download; | |
| | | | |
| // the number of seconds of being active | | // the number of seconds of being active | |
| // and as being a seed, saved and restored | | // and as being a seed, saved and restored | |
| // from resume data | | // from resume data | |
| int active_time; | | int active_time; | |
|
| | | int finished_time; | |
| int seeding_time; | | int seeding_time; | |
| | | | |
| // higher value means more important to seed | | // higher value means more important to seed | |
| int seed_rank; | | int seed_rank; | |
| | | | |
| // number of seconds since last scrape, or -1 if | | // number of seconds since last scrape, or -1 if | |
| // there hasn't been a scrape | | // there hasn't been a scrape | |
| int last_scrape; | | int last_scrape; | |
| | | | |
| // true if there are incoming connections to this | | // true if there are incoming connections to this | |
| // torrent | | // torrent | |
| bool has_incoming; | | bool has_incoming; | |
|
| | | | |
| | | // the number of "holes" in the torrent | |
| | | int sparse_regions; | |
| | | | |
| | | // is true if this torrent is (still) in seed_mode | |
| | | bool seed_mode; | |
| | | | |
| | | // this is set to true when the torrent is blocked | |
| | | // from downloading, typically caused by a file | |
| | | // write operation failing | |
| | | bool upload_mode; | |
| | | | |
| | | // the priority of this torrent | |
| | | int priority; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT block_info | | struct TORRENT_EXPORT block_info | |
| { | | { | |
| enum block_state_t | | enum block_state_t | |
| { none, requested, writing, finished }; | | { none, requested, writing, finished }; | |
| | | | |
|
| tcp::endpoint peer; | | private: | |
| | | #ifdef __SUNPRO_CC | |
| | | // sunpro is strict about POD types in unions | |
| | | struct | |
| | | #else | |
| | | union | |
| | | #endif | |
| | | { | |
| | | address_v4::bytes_type v4; | |
| | | address_v6::bytes_type v6; | |
| | | } addr; | |
| | | | |
| | | boost::uint16_t port; | |
| | | public: | |
| | | | |
| | | void set_peer(tcp::endpoint const& ep) | |
| | | { | |
| | | is_v6_addr = ep.address().is_v6(); | |
| | | if (is_v6_addr) | |
| | | addr.v6 = ep.address().to_v6().to_bytes(); | |
| | | else | |
| | | addr.v4 = ep.address().to_v4().to_bytes(); | |
| | | port = ep.port(); | |
| | | } | |
| | | | |
| | | tcp::endpoint peer() const | |
| | | { | |
| | | if (is_v6_addr) | |
| | | return tcp::endpoint(address_v6(addr.v6), po | |
| | | rt); | |
| | | else | |
| | | return tcp::endpoint(address_v4(addr.v4), po | |
| | | rt); | |
| | | } | |
| | | | |
| // number of bytes downloaded in this block | | // number of bytes downloaded in this block | |
|
| unsigned bytes_progress:16; | | unsigned bytes_progress:15; | |
| // the total number of bytes in this block | | // the total number of bytes in this block | |
|
| unsigned block_size:16; | | unsigned block_size:15; | |
| | | private: | |
| | | // the type of the addr union | |
| | | unsigned is_v6_addr:1; | |
| | | unsigned unused:1; | |
| | | public: | |
| // the state this block is in (see block_state_t) | | // the state this block is in (see block_state_t) | |
| unsigned state:2; | | unsigned state:2; | |
| // the number of peers that has requested this block | | // the number of peers that has requested this block | |
| // typically 0 or 1. If > 1, this block is in | | // typically 0 or 1. If > 1, this block is in | |
| // end game mode | | // end game mode | |
| unsigned num_peers:14; | | unsigned num_peers:14; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT partial_piece_info | | struct TORRENT_EXPORT partial_piece_info | |
| { | | { | |
|
| enum { max_blocks_per_piece = 512 }; | | | |
| int piece_index; | | int piece_index; | |
| int blocks_in_piece; | | int blocks_in_piece; | |
| // the number of blocks in the finished state | | // the number of blocks in the finished state | |
| int finished; | | int finished; | |
| // the number of blocks in the writing state | | // the number of blocks in the writing state | |
| int writing; | | int writing; | |
| // the number of blocks in the requested state | | // the number of blocks in the requested state | |
| int requested; | | int requested; | |
|
| block_info blocks[max_blocks_per_piece]; | | block_info* blocks; | |
| enum state_t { none, slow, medium, fast }; | | enum state_t { none, slow, medium, fast }; | |
| state_t piece_state; | | state_t piece_state; | |
| }; | | }; | |
| | | | |
| struct TORRENT_EXPORT torrent_handle | | struct TORRENT_EXPORT torrent_handle | |
| { | | { | |
| friend class invariant_access; | | friend class invariant_access; | |
| friend struct aux::session_impl; | | friend struct aux::session_impl; | |
| friend class torrent; | | friend class torrent; | |
| | | | |
| torrent_handle() {} | | torrent_handle() {} | |
| | | | |
|
| | | enum flags_t { overwrite_existing = 1 }; | |
| | | void add_piece(int piece, char const* data, int flags = 0) c | |
| | | onst; | |
| | | void read_piece(int piece) const; | |
| | | | |
| void get_full_peer_list(std::vector<peer_list_entry>& v) con
st; | | void get_full_peer_list(std::vector<peer_list_entry>& v) con
st; | |
| void get_peer_info(std::vector<peer_info>& v) const; | | void get_peer_info(std::vector<peer_info>& v) const; | |
| torrent_status status() const; | | torrent_status status() const; | |
| void get_download_queue(std::vector<partial_piece_info>& que
ue) const; | | void get_download_queue(std::vector<partial_piece_info>& que
ue) const; | |
| | | | |
|
| | | enum deadline_flags { alert_when_available = 1 }; | |
| | | void set_piece_deadline(int index, int deadline, int flags = | |
| | | 0) const; | |
| | | | |
| | | void set_priority(int prio) const; | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
|
| | | #if !TORRENT_NO_FPU | |
| // fills the specified vector with the download progress [0,
1] | | // fills the specified vector with the download progress [0,
1] | |
| // of each file in the torrent. The files are ordered as in | | // of each file in the torrent. The files are ordered as in | |
| // the torrent_info. | | // the torrent_info. | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| void file_progress(std::vector<float>& progress) const TORRE
NT_DEPRECATED; | | void file_progress(std::vector<float>& progress) const TORRE
NT_DEPRECATED; | |
| #endif | | #endif | |
|
| void file_progress(std::vector<size_type>& progress) const; | | #endif | |
| | | enum file_progress_flags_t | |
| | | { | |
| | | piece_granularity = 1 | |
| | | }; | |
| | | | |
| | | void file_progress(std::vector<size_type>& progress, int fla | |
| | | gs = 0) const; | |
| | | | |
| void clear_error() const; | | void clear_error() const; | |
| | | | |
|
| std::vector<announce_entry> const& trackers() const; | | std::vector<announce_entry> trackers() const; | |
| void replace_trackers(std::vector<announce_entry> const&) co
nst; | | void replace_trackers(std::vector<announce_entry> const&) co
nst; | |
|
| | | void add_tracker(announce_entry const&) const; | |
| | | | |
| void add_url_seed(std::string const& url) const; | | void add_url_seed(std::string const& url) const; | |
| void remove_url_seed(std::string const& url) const; | | void remove_url_seed(std::string const& url) const; | |
| std::set<std::string> url_seeds() const; | | std::set<std::string> url_seeds() const; | |
| | | | |
|
| | | void add_http_seed(std::string const& url) const; | |
| | | void remove_http_seed(std::string const& url) const; | |
| | | std::set<std::string> http_seeds() const; | |
| | | | |
| #ifndef TORRENT_DISABLE_EXTENSIONS | | #ifndef TORRENT_DISABLE_EXTENSIONS | |
| void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> const& ext | | void add_extension(boost::function<boost::shared_ptr<torrent
_plugin>(torrent*, void*)> const& ext | |
| , void* userdata = 0); | | , void* userdata = 0); | |
| #endif | | #endif | |
| | | | |
| bool has_metadata() const; | | bool has_metadata() const; | |
|
| | | bool set_metadata(char const* metadata, int size) const; | |
| const torrent_info& get_torrent_info() const; | | const torrent_info& get_torrent_info() const; | |
| bool is_valid() const; | | bool is_valid() const; | |
| | | | |
| bool is_seed() const; | | bool is_seed() const; | |
| bool is_finished() const; | | bool is_finished() const; | |
| bool is_paused() const; | | bool is_paused() const; | |
| void pause() const; | | void pause() const; | |
| void resume() const; | | void resume() const; | |
|
| | | void set_upload_mode(bool b) const; | |
| | | void flush_cache() const; | |
| | | | |
| void force_recheck() const; | | void force_recheck() const; | |
| void save_resume_data() const; | | void save_resume_data() const; | |
| | | | |
| bool is_auto_managed() const; | | bool is_auto_managed() const; | |
| void auto_managed(bool m) const; | | void auto_managed(bool m) const; | |
| | | | |
| int queue_position() const; | | int queue_position() const; | |
| void queue_position_up() const; | | void queue_position_up() const; | |
| void queue_position_down() const; | | void queue_position_down() const; | |
| void queue_position_top() const; | | void queue_position_top() const; | |
| | | | |
| skipping to change at line 381 | | skipping to change at line 473 | |
| | | | |
| // all these are deprecated, use piece | | // all these are deprecated, use piece | |
| // priority functions instead | | // priority functions instead | |
| | | | |
| // ================ start deprecation ============ | | // ================ start deprecation ============ | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // deprecated in 0.13 | | // deprecated in 0.13 | |
| // marks the piece with the given index as filtered | | // marks the piece with the given index as filtered | |
| // it will not be downloaded | | // it will not be downloaded | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| void filter_piece(int index, bool filter) const TORRENT_DEPR
ECATED; | | void filter_piece(int index, bool filter) const TORRENT_DEPR
ECATED; | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| void filter_pieces(std::vector<bool> const& pieces) const TO
RRENT_DEPRECATED; | | void filter_pieces(std::vector<bool> const& pieces) const TO
RRENT_DEPRECATED; | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| bool is_piece_filtered(int index) const TORRENT_DEPRECATED; | | bool is_piece_filtered(int index) const TORRENT_DEPRECATED; | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| std::vector<bool> filtered_pieces() const TORRENT_DEPRECATED
; | | std::vector<bool> filtered_pieces() const TORRENT_DEPRECATED
; | |
| // marks the file with the given index as filtered | | // marks the file with the given index as filtered | |
| // it will not be downloaded | | // it will not be downloaded | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| void filter_files(std::vector<bool> const& files) const TORR
ENT_DEPRECATED; | | void filter_files(std::vector<bool> const& files) const TORR
ENT_DEPRECATED; | |
| | | | |
| // ================ end deprecation ============ | | // ================ end deprecation ============ | |
| #endif | | #endif | |
| | | | |
| void piece_availability(std::vector<int>& avail) const; | | void piece_availability(std::vector<int>& avail) const; | |
| | | | |
| // priority must be within the range [0, 7] | | // priority must be within the range [0, 7] | |
| void piece_priority(int index, int priority) const; | | void piece_priority(int index, int priority) const; | |
| int piece_priority(int index) const; | | int piece_priority(int index) const; | |
| | | | |
| skipping to change at line 416 | | skipping to change at line 513 | |
| std::vector<int> file_priorities() const; | | std::vector<int> file_priorities() const; | |
| | | | |
| // set the interface to bind outgoing connections | | // set the interface to bind outgoing connections | |
| // to. | | // to. | |
| void use_interface(const char* net_interface) const; | | void use_interface(const char* net_interface) const; | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // deprecated in 0.14 | | // deprecated in 0.14 | |
| // use save_resume_data() instead. It is async. and | | // use save_resume_data() instead. It is async. and | |
| // will return the resume data in an alert | | // will return the resume data in an alert | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| entry write_resume_data() const TORRENT_DEPRECATED; | | entry write_resume_data() const TORRENT_DEPRECATED; | |
| #endif | | #endif | |
| | | | |
| // forces this torrent to reannounce | | // forces this torrent to reannounce | |
| // (make a rerequest from the tracker) | | // (make a rerequest from the tracker) | |
| void force_reannounce() const; | | void force_reannounce() const; | |
|
| | | #ifndef TORRENT_DISABLE_DHT | |
| | | // announces this torrent to the DHT immediately | |
| | | void force_dht_announce() const; | |
| | | #endif | |
| | | | |
| // forces a reannounce in the specified amount of time. | | // forces a reannounce in the specified amount of time. | |
| // This overrides the default announce interval, and no | | // This overrides the default announce interval, and no | |
| // announce will take place until the given time has | | // announce will take place until the given time has | |
| // timed out. | | // timed out. | |
| void force_reannounce(boost::posix_time::time_duration) cons
t; | | void force_reannounce(boost::posix_time::time_duration) cons
t; | |
| | | | |
| // performs a scrape request | | // performs a scrape request | |
| void scrape_tracker() const; | | void scrape_tracker() const; | |
| | | | |
| | | | |
| skipping to change at line 463 | | skipping to change at line 565 | |
| void connect_peer(tcp::endpoint const& adr, int source = 0)
const; | | void connect_peer(tcp::endpoint const& adr, int source = 0)
const; | |
| | | | |
| // valid ratios are 0 (infinite ratio) or [ 1.0 , inf ) | | // valid ratios are 0 (infinite ratio) or [ 1.0 , inf ) | |
| // the ratio is uploaded / downloaded. less than 1 is not al
lowed | | // the ratio is uploaded / downloaded. less than 1 is not al
lowed | |
| void set_ratio(float up_down_ratio) const; | | void set_ratio(float up_down_ratio) const; | |
| | | | |
| fs::path save_path() const; | | fs::path save_path() const; | |
| | | | |
| // -1 means unlimited unchokes | | // -1 means unlimited unchokes | |
| void set_max_uploads(int max_uploads) const; | | void set_max_uploads(int max_uploads) const; | |
|
| | | int max_uploads() const; | |
| | | | |
| // -1 means unlimited connections | | // -1 means unlimited connections | |
| void set_max_connections(int max_connections) const; | | void set_max_connections(int max_connections) const; | |
|
| | | int max_connections() const; | |
| | | | |
| void set_tracker_login(std::string const& name | | void set_tracker_login(std::string const& name | |
| , std::string const& password) const; | | , std::string const& password) const; | |
| | | | |
| // post condition: save_path() == save_path if true is retur
ned | | // post condition: save_path() == save_path if true is retur
ned | |
| void move_storage(fs::path const& save_path) const; | | void move_storage(fs::path const& save_path) const; | |
| void rename_file(int index, fs::path const& new_name) const; | | void rename_file(int index, fs::path const& new_name) const; | |
| | | | |
|
| | | #ifndef BOOST_FILESYSTEM_NARROW_ONLY | |
| | | void move_storage(fs::wpath const& save_path) const; | |
| | | void rename_file(int index, fs::wpath const& new_name) const | |
| | | ; | |
| | | #endif | |
| | | | |
| | | bool super_seeding() const; | |
| | | void super_seeding(bool on) const; | |
| | | | |
| sha1_hash info_hash() const; | | sha1_hash info_hash() const; | |
| | | | |
| bool operator==(const torrent_handle& h) const | | bool operator==(const torrent_handle& h) const | |
| { return m_torrent.lock() == h.m_torrent.lock(); } | | { return m_torrent.lock() == h.m_torrent.lock(); } | |
| | | | |
| bool operator!=(const torrent_handle& h) const | | bool operator!=(const torrent_handle& h) const | |
| { return m_torrent.lock() != h.m_torrent.lock(); } | | { return m_torrent.lock() != h.m_torrent.lock(); } | |
| | | | |
| bool operator<(const torrent_handle& h) const | | bool operator<(const torrent_handle& h) const | |
| { return m_torrent.lock() < h.m_torrent.lock(); } | | { return m_torrent.lock() < h.m_torrent.lock(); } | |
| | | | |
End of changes. 35 change blocks. |
| 22 lines changed or deleted | | 140 lines changed or added | |
|
| torrent_info.hpp | | torrent_info.hpp | |
| | | | |
| skipping to change at line 38 | | skipping to change at line 38 | |
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| POSSIBILITY OF SUCH DAMAGE. | | POSSIBILITY OF SUCH DAMAGE. | |
| | | | |
| */ | | */ | |
| | | | |
| #ifndef TORRENT_TORRENT_INFO_HPP_INCLUDED | | #ifndef TORRENT_TORRENT_INFO_HPP_INCLUDED | |
| #define TORRENT_TORRENT_INFO_HPP_INCLUDED | | #define TORRENT_TORRENT_INFO_HPP_INCLUDED | |
| | | | |
| #include <string> | | #include <string> | |
| #include <vector> | | #include <vector> | |
|
| #include <iosfwd> | | //#include <iosfwd> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| #pragma warning(push, 1) | | #pragma warning(push, 1) | |
| #endif | | #endif | |
| | | | |
| #include <boost/optional.hpp> | | #include <boost/optional.hpp> | |
| #include <boost/filesystem/path.hpp> | | #include <boost/filesystem/path.hpp> | |
| #include <boost/shared_array.hpp> | | #include <boost/shared_array.hpp> | |
| | | | |
| #ifdef _MSC_VER | | #ifdef _MSC_VER | |
| | | | |
| skipping to change at line 69 | | skipping to change at line 69 | |
| #include "libtorrent/intrusive_ptr_base.hpp" | | #include "libtorrent/intrusive_ptr_base.hpp" | |
| #include "libtorrent/assert.hpp" | | #include "libtorrent/assert.hpp" | |
| #include "libtorrent/file_storage.hpp" | | #include "libtorrent/file_storage.hpp" | |
| | | | |
| namespace libtorrent | | namespace libtorrent | |
| { | | { | |
| namespace pt = boost::posix_time; | | namespace pt = boost::posix_time; | |
| namespace gr = boost::gregorian; | | namespace gr = boost::gregorian; | |
| namespace fs = boost::filesystem; | | namespace fs = boost::filesystem; | |
| | | | |
|
| | | enum | |
| | | { | |
| | | // wait 60 seconds before retrying a failed tracker | |
| | | tracker_retry_delay_min = 10 | |
| | | // when tracker_failed_max trackers | |
| | | // has failed, wait 60 minutes instead | |
| | | , tracker_retry_delay_max = 60 * 60 | |
| | | }; | |
| | | | |
| struct TORRENT_EXPORT announce_entry | | struct TORRENT_EXPORT announce_entry | |
| { | | { | |
|
| announce_entry(std::string const& u): url(u), tier(0) {} | | announce_entry(std::string const& u) | |
| | | : url(u) | |
| | | , tier(0) | |
| | | , fail_limit(3) | |
| | | , fails(0) | |
| | | , source(0) | |
| | | , verified(false) | |
| | | , updating(false) | |
| | | , start_sent(false) | |
| | | , complete_sent(false) | |
| | | , send_stats(true) | |
| | | {} | |
| | | | |
| std::string url; | | std::string url; | |
|
| int tier; | | | |
| | | int next_announce_in() const; | |
| | | int min_announce_in() const; | |
| | | | |
| | | // the time of next tracker announce | |
| | | ptime next_announce; | |
| | | | |
| | | // no announces before this time | |
| | | ptime min_announce; | |
| | | | |
| | | boost::uint8_t tier; | |
| | | // the number of times this tracker can fail | |
| | | // in a row before it's removed. 0 means unlimited | |
| | | boost::uint8_t fail_limit; | |
| | | | |
| | | // the number of times in a row this tracker has failed | |
| | | boost::uint8_t fails; | |
| | | | |
| | | enum tracker_source | |
| | | { | |
| | | source_torrent = 1, | |
| | | source_client = 2, | |
| | | source_magnet_link = 4, | |
| | | source_tex = 8 | |
| | | }; | |
| | | // where did we get this tracker from | |
| | | boost::uint8_t source; | |
| | | | |
| | | // is set to true if we have ever received a response from | |
| | | // this tracker | |
| | | bool verified:1; | |
| | | | |
| | | // true if we're currently trying to announce with | |
| | | // this tracker | |
| | | bool updating:1; | |
| | | | |
| | | // this is true if event start has been sent to the tracker | |
| | | bool start_sent:1; | |
| | | | |
| | | // this is true if event completed has been sent to the trac | |
| | | ker | |
| | | bool complete_sent:1; | |
| | | | |
| | | // this is false the stats sent to this tracker will be 0 | |
| | | bool send_stats:1; | |
| | | | |
| | | void reset() | |
| | | { | |
| | | start_sent = false; | |
| | | next_announce = min_time(); | |
| | | min_announce = min_time(); | |
| | | } | |
| | | | |
| | | void failed(int retry_interval = 0) | |
| | | { | |
| | | ++fails; | |
| | | int delay = (std::min)(tracker_retry_delay_min + int | |
| | | (fails) * int(fails) | |
| | | * tracker_retry_delay_min, int(tracker_retry | |
| | | _delay_max)); | |
| | | delay = (std::max)(delay, retry_interval); | |
| | | next_announce = time_now() + seconds(delay); | |
| | | updating = false; | |
| | | } | |
| | | | |
| | | bool can_announce(ptime now) const | |
| | | { | |
| | | return now >= next_announce | |
| | | && now >= min_announce | |
| | | && (fails < fail_limit || fail_limit == 0) | |
| | | && !updating; | |
| | | } | |
| | | | |
| | | bool is_working() const | |
| | | { | |
| | | return fails == 0; | |
| | | } | |
| | | | |
| | | void trim() | |
| | | { | |
| | | while (!url.empty() && is_space(url[0])) | |
| | | url.erase(url.begin()); | |
| | | } | |
| }; | | }; | |
| | | | |
| #ifndef BOOST_NO_EXCEPTIONS | | #ifndef BOOST_NO_EXCEPTIONS | |
|
| struct TORRENT_EXPORT invalid_torrent_file: std::exception | | // for backwards compatibility with 0.14 | |
| { | | typedef libtorrent_exception invalid_torrent_file; | |
| virtual const char* what() const throw() { return "invalid t | | | |
| orrent file"; } | | | |
| }; | | | |
| #endif | | #endif | |
| | | | |
| int TORRENT_EXPORT load_file(fs::path const& filename, std::vector<c
har>& v); | | int TORRENT_EXPORT load_file(fs::path const& filename, std::vector<c
har>& v); | |
| | | | |
| class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torren
t_info> | | class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torren
t_info> | |
| { | | { | |
| public: | | public: | |
|
| | | torrent_info(torrent_info const& t); | |
| torrent_info(sha1_hash const& info_hash); | | #ifndef BOOST_NO_EXCEPTIONS | |
| torrent_info(lazy_entry const& torrent_file); | | torrent_info(lazy_entry const& torrent_file); | |
| torrent_info(char const* buffer, int size); | | torrent_info(char const* buffer, int size); | |
| torrent_info(fs::path const& filename); | | torrent_info(fs::path const& filename); | |
|
| | | #ifndef BOOST_FILESYSTEM_NARROW_ONLY | |
| | | torrent_info(fs::wpath const& filename); | |
| | | #endif | |
| | | #endif | |
| | | | |
| | | torrent_info(sha1_hash const& info_hash); | |
| | | torrent_info(lazy_entry const& torrent_file, error_code& ec) | |
| | | ; | |
| | | torrent_info(char const* buffer, int size, error_code& ec); | |
| | | torrent_info(fs::path const& filename, error_code& ec); | |
| | | #ifndef BOOST_FILESYSTEM_NARROW_ONLY | |
| | | torrent_info(fs::wpath const& filename, error_code& ec); | |
| | | #endif | |
| | | | |
| ~torrent_info(); | | ~torrent_info(); | |
| | | | |
| file_storage const& files() const { return m_files; } | | file_storage const& files() const { return m_files; } | |
| file_storage const& orig_files() const { return m_orig_files
? *m_orig_files : m_files; } | | file_storage const& orig_files() const { return m_orig_files
? *m_orig_files : m_files; } | |
| | | | |
| void rename_file(int index, std::string const& new_filename) | | void rename_file(int index, std::string const& new_filename) | |
| { | | { | |
| copy_on_write(); | | copy_on_write(); | |
| m_files.rename_file(index, new_filename); | | m_files.rename_file(index, new_filename); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_FILESYSTEM_NARROW_ONLY | |
| | | void rename_file(int index, std::wstring const& new_filename | |
| | | ) | |
| | | { | |
| | | copy_on_write(); | |
| | | m_files.rename_file(index, new_filename); | |
| | | } | |
| | | #endif | |
| | | | |
| | | void remap_files(file_storage const& f); | |
| | | | |
| void add_tracker(std::string const& url, int tier = 0); | | void add_tracker(std::string const& url, int tier = 0); | |
| std::vector<announce_entry> const& trackers() const { return
m_urls; } | | std::vector<announce_entry> const& trackers() const { return
m_urls; } | |
| | | | |
| std::vector<std::string> const& url_seeds() const | | std::vector<std::string> const& url_seeds() const | |
| { return m_url_seeds; } | | { return m_url_seeds; } | |
| void add_url_seed(std::string const& url) | | void add_url_seed(std::string const& url) | |
| { m_url_seeds.push_back(url); } | | { m_url_seeds.push_back(url); } | |
| | | | |
|
| | | std::vector<std::string> const& http_seeds() const | |
| | | { return m_http_seeds; } | |
| | | void add_http_seed(std::string const& url) | |
| | | { m_http_seeds.push_back(url); } | |
| | | | |
| size_type total_size() const { return m_files.total_size();
} | | size_type total_size() const { return m_files.total_size();
} | |
| int piece_length() const { return m_files.piece_length(); } | | int piece_length() const { return m_files.piece_length(); } | |
| int num_pieces() const { return m_files.num_pieces(); } | | int num_pieces() const { return m_files.num_pieces(); } | |
| const sha1_hash& info_hash() const { return m_info_hash; } | | const sha1_hash& info_hash() const { return m_info_hash; } | |
| const std::string& name() const { return m_files.name(); } | | const std::string& name() const { return m_files.name(); } | |
| | | | |
| typedef file_storage::iterator file_iterator; | | typedef file_storage::iterator file_iterator; | |
| typedef file_storage::reverse_iterator reverse_file_iterator
; | | typedef file_storage::reverse_iterator reverse_file_iterator
; | |
| | | | |
| file_iterator begin_files() const { return m_files.begin();
} | | file_iterator begin_files() const { return m_files.begin();
} | |
| | | | |
| skipping to change at line 138 | | skipping to change at line 264 | |
| file_iterator file_at_offset(size_type offset) const | | file_iterator file_at_offset(size_type offset) const | |
| { return m_files.file_at_offset(offset); } | | { return m_files.file_at_offset(offset); } | |
| std::vector<file_slice> map_block(int piece, size_type offse
t, int size) const | | std::vector<file_slice> map_block(int piece, size_type offse
t, int size) const | |
| { return m_files.map_block(piece, offset, size); } | | { return m_files.map_block(piece, offset, size); } | |
| peer_request map_file(int file, size_type offset, int size)
const | | peer_request map_file(int file, size_type offset, int size)
const | |
| { return m_files.map_file(file, offset, size); } | | { return m_files.map_file(file, offset, size); } | |
| | | | |
| #ifndef TORRENT_NO_DEPRECATE | | #ifndef TORRENT_NO_DEPRECATE | |
| // ------- start deprecation ------- | | // ------- start deprecation ------- | |
| // these functions will be removed in a future version | | // these functions will be removed in a future version | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; | | torrent_info(entry const& torrent_file) TORRENT_DEPRECATED; | |
|
| | | TORRENT_DEPRECATED_PREFIX | |
| void print(std::ostream& os) const TORRENT_DEPRECATED; | | void print(std::ostream& os) const TORRENT_DEPRECATED; | |
|
| file_storage& files() TORRENT_DEPRECATED { return m_files; } | | | |
| // ------- end deprecation ------- | | // ------- end deprecation ------- | |
| #endif | | #endif | |
| | | | |
| bool is_valid() const { return m_files.is_valid(); } | | bool is_valid() const { return m_files.is_valid(); } | |
| | | | |
| bool priv() const { return m_private; } | | bool priv() const { return m_private; } | |
| | | | |
| int piece_size(int index) const { return m_files.piece_size(
index); } | | int piece_size(int index) const { return m_files.piece_size(
index); } | |
| | | | |
| sha1_hash hash_for_piece(int index) const | | sha1_hash hash_for_piece(int index) const | |
| { return sha1_hash(hash_for_piece_ptr(index)); } | | { return sha1_hash(hash_for_piece_ptr(index)); } | |
| | | | |
|
| | | std::vector<sha1_hash> const& merkle_tree() const { return m | |
| | | _merkle_tree; } | |
| | | void set_merkle_tree(std::vector<sha1_hash>& h) | |
| | | { TORRENT_ASSERT(h.size() == m_merkle_tree.size() ); m_merkl | |
| | | e_tree.swap(h); } | |
| | | | |
| char const* hash_for_piece_ptr(int index) const | | char const* hash_for_piece_ptr(int index) const | |
| { | | { | |
| TORRENT_ASSERT(index >= 0); | | TORRENT_ASSERT(index >= 0); | |
| TORRENT_ASSERT(index < m_files.num_pieces()); | | TORRENT_ASSERT(index < m_files.num_pieces()); | |
|
| TORRENT_ASSERT(m_piece_hashes); | | if (is_merkle_torrent()) | |
| TORRENT_ASSERT(m_piece_hashes >= m_info_section.get( | | { | |
| )); | | TORRENT_ASSERT(index < int(m_merkle_tree.siz | |
| TORRENT_ASSERT(m_piece_hashes < m_info_section.get() | | e()) - m_merkle_first_leaf); | |
| + m_info_section_size); | | return (const char*)&m_merkle_tree[m_merkle_ | |
| return &m_piece_hashes[index*20]; | | first_leaf + index][0]; | |
| | | } | |
| | | else | |
| | | { | |
| | | TORRENT_ASSERT(m_piece_hashes); | |
| | | TORRENT_ASSERT(m_piece_hashes >= m_info_sect | |
| | | ion.get()); | |
| | | TORRENT_ASSERT(m_piece_hashes < m_info_secti | |
| | | on.get() + m_info_section_size); | |
| | | TORRENT_ASSERT(index < m_info_section_size / | |
| | | 20); | |
| | | return &m_piece_hashes[index*20]; | |
| | | } | |
| } | | } | |
| | | | |
| boost::optional<pt::ptime> creation_date() const; | | boost::optional<pt::ptime> creation_date() const; | |
| | | | |
| const std::string& creator() const | | const std::string& creator() const | |
| { return m_created_by; } | | { return m_created_by; } | |
| | | | |
| const std::string& comment() const | | const std::string& comment() const | |
| { return m_comment; } | | { return m_comment; } | |
| | | | |
| // dht nodes to add to the routing table/bootstrap from | | // dht nodes to add to the routing table/bootstrap from | |
| typedef std::vector<std::pair<std::string, int> > nodes_t; | | typedef std::vector<std::pair<std::string, int> > nodes_t; | |
| | | | |
| nodes_t const& nodes() const | | nodes_t const& nodes() const | |
| { return m_nodes; } | | { return m_nodes; } | |
| void add_node(std::pair<std::string, int> const& node) | | void add_node(std::pair<std::string, int> const& node) | |
| { m_nodes.push_back(node); } | | { m_nodes.push_back(node); } | |
| | | | |
|
| bool parse_info_section(lazy_entry const& e, std::string& er
ror); | | bool parse_info_section(lazy_entry const& e, error_code& ex)
; | |
| | | | |
| lazy_entry const* info(char const* key) const | | lazy_entry const* info(char const* key) const | |
| { | | { | |
| if (m_info_dict.type() == lazy_entry::none_t) | | if (m_info_dict.type() == lazy_entry::none_t) | |
| lazy_bdecode(m_info_section.get(), m_info_se
ction.get() | | lazy_bdecode(m_info_section.get(), m_info_se
ction.get() | |
| + m_info_section_size, m_info_dict); | | + m_info_section_size, m_info_dict); | |
| return m_info_dict.dict_find(key); | | return m_info_dict.dict_find(key); | |
| } | | } | |
| | | | |
| void swap(torrent_info& ti); | | void swap(torrent_info& ti); | |
| | | | |
| boost::shared_array<char> metadata() const | | boost::shared_array<char> metadata() const | |
| { return m_info_section; } | | { return m_info_section; } | |
| | | | |
| int metadata_size() const { return m_info_section_size; } | | int metadata_size() const { return m_info_section_size; } | |
| | | | |
|
| | | bool add_merkle_nodes(std::map<int, sha1_hash> const& subtre | |
| | | e | |
| | | , int piece); | |
| | | std::map<int, sha1_hash> build_merkle_list(int piece) const; | |
| | | bool is_merkle_torrent() const { return !m_merkle_tree.empty | |
| | | (); } | |
| | | | |
| private: | | private: | |
| | | | |
|
| | | // not assignable | |
| | | torrent_info const& operator=(torrent_info const&); | |
| | | | |
| void copy_on_write(); | | void copy_on_write(); | |
|
| bool parse_torrent_file(lazy_entry const& libtorrent, std::s
tring& error); | | bool parse_torrent_file(lazy_entry const& libtorrent, error_
code& ec); | |
| | | | |
| file_storage m_files; | | file_storage m_files; | |
| | | | |
| // if m_files is modified, it is first copied into | | // if m_files is modified, it is first copied into | |
| // m_orig_files so that the original name and | | // m_orig_files so that the original name and | |
| // filenames are preserved. | | // filenames are preserved. | |
| boost::shared_ptr<const file_storage> m_orig_files; | | boost::shared_ptr<const file_storage> m_orig_files; | |
| | | | |
| // the urls to the trackers | | // the urls to the trackers | |
| std::vector<announce_entry> m_urls; | | std::vector<announce_entry> m_urls; | |
| std::vector<std::string> m_url_seeds; | | std::vector<std::string> m_url_seeds; | |
|
| | | std::vector<std::string> m_http_seeds; | |
| nodes_t m_nodes; | | nodes_t m_nodes; | |
| | | | |
| // the hash that identifies this torrent | | // the hash that identifies this torrent | |
| sha1_hash m_info_hash; | | sha1_hash m_info_hash; | |
| | | | |
| // if a creation date is found in the torrent file | | // if a creation date is found in the torrent file | |
| // this will be set to that, otherwise it'll be | | // this will be set to that, otherwise it'll be | |
| // 1970, Jan 1 | | // 1970, Jan 1 | |
| pt::ptime m_creation_date; | | pt::ptime m_creation_date; | |
| | | | |
| | | | |
| skipping to change at line 250 | | skipping to change at line 399 | |
| // this is a copy of the info section from the torrent. | | // this is a copy of the info section from the torrent. | |
| // it use maintained in this flat format in order to | | // it use maintained in this flat format in order to | |
| // make it available through the metadata extension | | // make it available through the metadata extension | |
| boost::shared_array<char> m_info_section; | | boost::shared_array<char> m_info_section; | |
| int m_info_section_size; | | int m_info_section_size; | |
| | | | |
| // this is a pointer into the m_info_section buffer | | // this is a pointer into the m_info_section buffer | |
| // pointing to the first byte of the first sha-1 hash | | // pointing to the first byte of the first sha-1 hash | |
| char const* m_piece_hashes; | | char const* m_piece_hashes; | |
| | | | |
|
| | | // if this is a merkle torrent, this is the merkle | |
| | | // tree. It has space for merkle_num_nodes(merkle_num_leafs( | |
| | | num_pieces)) | |
| | | // hashes | |
| | | std::vector<sha1_hash> m_merkle_tree; | |
| | | // the index to the first leaf. This is where the hash for t | |
| | | he | |
| | | // first piece is stored | |
| | | int m_merkle_first_leaf; | |
| | | | |
| // the info section parsed. points into m_info_section | | // the info section parsed. points into m_info_section | |
| // parsed lazily | | // parsed lazily | |
| mutable lazy_entry m_info_dict; | | mutable lazy_entry m_info_dict; | |
| }; | | }; | |
| | | | |
| } | | } | |
| | | | |
| #endif // TORRENT_TORRENT_INFO_HPP_INCLUDED | | #endif // TORRENT_TORRENT_INFO_HPP_INCLUDED | |
| | | | |
End of changes. 20 change blocks. |
| 19 lines changed or deleted | | 189 lines changed or added | |
|
| variant_stream.hpp | | variant_stream.hpp | |
| | | | |
| skipping to change at line 55 | | skipping to change at line 55 | |
| | | | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| }; | | }; | |
| | | | |
| // -------------- io_control ----------- | | // -------------- io_control ----------- | |
| | | | |
| template<class IO_Control_Command> | | template<class IO_Control_Command> | |
| struct io_control_visitor_ec: boost::static_visitor<> | | struct io_control_visitor_ec: boost::static_visitor<> | |
| { | | { | |
|
| io_control_visitor_ec(IO_Control_Command& ioc, error_code& ec_) | | io_control_visitor_ec(IO_Control_Command& io, error_code& e) | |
| : ioc(ioc), ec(ec_) {} | | : ioc(io), ec(e) {} | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { | | { | |
| p->io_control(ioc, ec); | | p->io_control(ioc, ec); | |
| } | | } | |
| | | | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| | | | |
| IO_Control_Command& ioc; | | IO_Control_Command& ioc; | |
| error_code& ec; | | error_code& ec; | |
| }; | | }; | |
| | | | |
| template<class IO_Control_Command> | | template<class IO_Control_Command> | |
| struct io_control_visitor | | struct io_control_visitor | |
| : boost::static_visitor<> | | : boost::static_visitor<> | |
| { | | { | |
|
| io_control_visitor(IO_Control_Command& ioc) | | io_control_visitor(IO_Control_Command& io) | |
| : ioc(ioc) {} | | : ioc(io) {} | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { | | { | |
| p->io_control(ioc); | | p->io_control(ioc); | |
| } | | } | |
| | | | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| | | | |
| IO_Control_Command& ioc; | | IO_Control_Command& ioc; | |
| }; | | }; | |
| // -------------- async_connect ----------- | | // -------------- async_connect ----------- | |
| | | | |
| template <class EndpointType, class Handler> | | template <class EndpointType, class Handler> | |
| struct async_connect_visitor | | struct async_connect_visitor | |
| : boost::static_visitor<> | | : boost::static_visitor<> | |
| { | | { | |
|
| async_connect_visitor(EndpointType const& endpoint, Handler const& ha | | async_connect_visitor(EndpointType const& ep, Handler const& h) | |
| ndler) | | : endpoint(ep) | |
| : endpoint(endpoint) | | , handler(h) | |
| , handler(handler) | | | |
| {} | | {} | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { | | { | |
| p->async_connect(endpoint, handler); | | p->async_connect(endpoint, handler); | |
| } | | } | |
| | | | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| | | | |
| skipping to change at line 221 | | skipping to change at line 221 | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { p->close(ec); } | | { p->close(ec); } | |
| | | | |
| void operator()(boost::blank) const {} | | void operator()(boost::blank) const {} | |
| | | | |
| error_code& ec; | | error_code& ec; | |
| }; | | }; | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| struct close_visitor | | struct close_visitor | |
| : boost::static_visitor<> | | : boost::static_visitor<> | |
| { | | { | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { p->close(); } | | { p->close(); } | |
| | | | |
| void operator()(boost::blank) const {} | | void operator()(boost::blank) const {} | |
| }; | | }; | |
|
| | | #endif | |
| | | | |
| // -------------- remote_endpoint ----------- | | // -------------- remote_endpoint ----------- | |
| | | | |
| template <class EndpointType> | | template <class EndpointType> | |
| struct remote_endpoint_visitor_ec | | struct remote_endpoint_visitor_ec | |
| : boost::static_visitor<EndpointType> | | : boost::static_visitor<EndpointType> | |
| { | | { | |
| remote_endpoint_visitor_ec(error_code& ec_) | | remote_endpoint_visitor_ec(error_code& ec_) | |
| : ec(ec_) | | : ec(ec_) | |
| {} | | {} | |
| | | | |
| skipping to change at line 251 | | skipping to change at line 253 | |
| template <class T> | | template <class T> | |
| EndpointType operator()(T const* p) const | | EndpointType operator()(T const* p) const | |
| { return p->remote_endpoint(ec); } | | { return p->remote_endpoint(ec); } | |
| | | | |
| EndpointType operator()(boost::blank) const | | EndpointType operator()(boost::blank) const | |
| { return EndpointType(); } | | { return EndpointType(); } | |
| | | | |
| error_code& ec; | | error_code& ec; | |
| }; | | }; | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class EndpointType> | | template <class EndpointType> | |
| struct remote_endpoint_visitor | | struct remote_endpoint_visitor | |
| : boost::static_visitor<EndpointType> | | : boost::static_visitor<EndpointType> | |
| { | | { | |
| template <class T> | | template <class T> | |
| EndpointType operator()(T const* p) const | | EndpointType operator()(T const* p) const | |
| { return p->remote_endpoint(); } | | { return p->remote_endpoint(); } | |
| | | | |
| EndpointType operator()(boost::blank) const | | EndpointType operator()(boost::blank) const | |
| { return EndpointType(); } | | { return EndpointType(); } | |
| }; | | }; | |
|
| | | #endif | |
| | | | |
| // -------------- set_option ----------- | | // -------------- set_option ----------- | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class SettableSocketOption> | | template <class SettableSocketOption> | |
| struct set_option_visitor | | struct set_option_visitor | |
| : boost::static_visitor<> | | : boost::static_visitor<> | |
| { | | { | |
| set_option_visitor(SettableSocketOption const& opt) | | set_option_visitor(SettableSocketOption const& opt) | |
| : opt_(opt) | | : opt_(opt) | |
| {} | | {} | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { p->set_option(opt_); } | | { p->set_option(opt_); } | |
| | | | |
| void operator()(boost::blank) const {} | | void operator()(boost::blank) const {} | |
| | | | |
| SettableSocketOption const& opt_; | | SettableSocketOption const& opt_; | |
| }; | | }; | |
|
| | | #endif | |
| | | | |
| template <class SettableSocketOption> | | template <class SettableSocketOption> | |
| struct set_option_visitor_ec | | struct set_option_visitor_ec | |
| : boost::static_visitor<error_code> | | : boost::static_visitor<error_code> | |
| { | | { | |
| set_option_visitor_ec(SettableSocketOption const& opt, error_code& ec
) | | set_option_visitor_ec(SettableSocketOption const& opt, error_code& ec
) | |
| : opt_(opt) | | : opt_(opt) | |
| , ec_(ec) | | , ec_(ec) | |
| {} | | {} | |
| | | | |
| | | | |
| skipping to change at line 326 | | skipping to change at line 332 | |
| } | | } | |
| | | | |
| EndpointType operator()(boost::blank) const | | EndpointType operator()(boost::blank) const | |
| { | | { | |
| return EndpointType(); | | return EndpointType(); | |
| } | | } | |
| | | | |
| error_code& ec; | | error_code& ec; | |
| }; | | }; | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class EndpointType> | | template <class EndpointType> | |
| struct local_endpoint_visitor | | struct local_endpoint_visitor | |
| : boost::static_visitor<EndpointType> | | : boost::static_visitor<EndpointType> | |
| { | | { | |
| template <class T> | | template <class T> | |
| EndpointType operator()(T const* p) const | | EndpointType operator()(T const* p) const | |
| { | | { | |
| return p->local_endpoint(); | | return p->local_endpoint(); | |
| } | | } | |
| | | | |
| EndpointType operator()(boost::blank) const | | EndpointType operator()(boost::blank) const | |
| { | | { | |
| return EndpointType(); | | return EndpointType(); | |
| } | | } | |
| }; | | }; | |
|
| | | #endif | |
| | | | |
| // -------------- async_read_some ----------- | | // -------------- async_read_some ----------- | |
| | | | |
| template <class Mutable_Buffers, class Handler> | | template <class Mutable_Buffers, class Handler> | |
| struct async_read_some_visitor | | struct async_read_some_visitor | |
| : boost::static_visitor<> | | : boost::static_visitor<> | |
| { | | { | |
|
| async_read_some_visitor(Mutable_Buffers const& buffers, Handler const | | async_read_some_visitor(Mutable_Buffers const& bufs, Handler const& h | |
| & handler) | | ) | |
| : buffers(buffers) | | : buffers(bufs) | |
| , handler(handler) | | , handler(h) | |
| {} | | {} | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { | | { | |
| p->async_read_some(buffers, handler); | | p->async_read_some(buffers, handler); | |
| } | | } | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| | | | |
| Mutable_Buffers const& buffers; | | Mutable_Buffers const& buffers; | |
| Handler const& handler; | | Handler const& handler; | |
| }; | | }; | |
| | | | |
| // -------------- read_some ----------- | | // -------------- read_some ----------- | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class Mutable_Buffers> | | template <class Mutable_Buffers> | |
| struct read_some_visitor | | struct read_some_visitor | |
| : boost::static_visitor<std::size_t> | | : boost::static_visitor<std::size_t> | |
| { | | { | |
|
| read_some_visitor(Mutable_Buffers const& buffers) | | read_some_visitor(Mutable_Buffers const& bufs) | |
| : buffers(buffers) | | : buffers(bufs) | |
| {} | | {} | |
| | | | |
| template <class T> | | template <class T> | |
| std::size_t operator()(T* p) const | | std::size_t operator()(T* p) const | |
| { return p->read_some(buffers); } | | { return p->read_some(buffers); } | |
| | | | |
| std::size_t operator()(boost::blank) const | | std::size_t operator()(boost::blank) const | |
| { return 0; } | | { return 0; } | |
| | | | |
| Mutable_Buffers const& buffers; | | Mutable_Buffers const& buffers; | |
| }; | | }; | |
|
| | | #endif | |
| | | | |
| template <class Mutable_Buffers> | | template <class Mutable_Buffers> | |
| struct read_some_visitor_ec | | struct read_some_visitor_ec | |
| : boost::static_visitor<std::size_t> | | : boost::static_visitor<std::size_t> | |
| { | | { | |
|
| read_some_visitor_ec(Mutable_Buffers const& buffers, error_code& ec_) | | read_some_visitor_ec(Mutable_Buffers const& bufs, error_code& e) | |
| : buffers(buffers) | | : buffers(bufs) | |
| , ec(ec_) | | , ec(e) | |
| {} | | {} | |
| | | | |
| template <class T> | | template <class T> | |
| std::size_t operator()(T* p) const | | std::size_t operator()(T* p) const | |
| { return p->read_some(buffers, ec); } | | { return p->read_some(buffers, ec); } | |
| | | | |
| std::size_t operator()(boost::blank) const | | std::size_t operator()(boost::blank) const | |
| { return 0; } | | { return 0; } | |
| | | | |
| Mutable_Buffers const& buffers; | | Mutable_Buffers const& buffers; | |
| error_code& ec; | | error_code& ec; | |
| }; | | }; | |
| | | | |
| // -------------- async_write_some ----------- | | // -------------- async_write_some ----------- | |
| | | | |
| template <class Const_Buffers, class Handler> | | template <class Const_Buffers, class Handler> | |
| struct async_write_some_visitor | | struct async_write_some_visitor | |
| : boost::static_visitor<> | | : boost::static_visitor<> | |
| { | | { | |
|
| async_write_some_visitor(Const_Buffers const& buffers, Handler const& | | async_write_some_visitor(Const_Buffers const& bufs, Handler const& h) | |
| handler) | | : buffers(bufs) | |
| : buffers(buffers) | | , handler(h) | |
| , handler(handler) | | | |
| {} | | {} | |
| | | | |
| template <class T> | | template <class T> | |
| void operator()(T* p) const | | void operator()(T* p) const | |
| { | | { | |
| p->async_write_some(buffers, handler); | | p->async_write_some(buffers, handler); | |
| } | | } | |
| | | | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| | | | |
| skipping to change at line 452 | | skipping to change at line 462 | |
| } | | } | |
| | | | |
| std::size_t operator()(boost::blank) const | | std::size_t operator()(boost::blank) const | |
| { | | { | |
| return 0; | | return 0; | |
| } | | } | |
| | | | |
| error_code& ec; | | error_code& ec; | |
| }; | | }; | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| struct in_avail_visitor | | struct in_avail_visitor | |
| : boost::static_visitor<std::size_t> | | : boost::static_visitor<std::size_t> | |
| { | | { | |
| template <class T> | | template <class T> | |
| std::size_t operator()(T const* p) const | | std::size_t operator()(T const* p) const | |
| { | | { | |
| return p->in_avail(); | | return p->in_avail(); | |
| } | | } | |
| | | | |
| void operator()(boost::blank) const | | void operator()(boost::blank) const | |
| {} | | {} | |
| }; | | }; | |
|
| | | #endif | |
| | | | |
| // -------------- io_service ----------- | | // -------------- io_service ----------- | |
| | | | |
| template <class IOService> | | template <class IOService> | |
| struct io_service_visitor | | struct io_service_visitor | |
| : boost::static_visitor<IOService&> | | : boost::static_visitor<IOService&> | |
| { | | { | |
| template <class T> | | template <class T> | |
| IOService& operator()(T* p) const | | IOService& operator()(T* p) const | |
| { | | { | |
| | | | |
| skipping to change at line 572 | | skipping to change at line 584 | |
| template <class Mutable_Buffers> | | template <class Mutable_Buffers> | |
| std::size_t read_some(Mutable_Buffers const& buffers, error_code& ec) | | std::size_t read_some(Mutable_Buffers const& buffers, error_code& ec) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor( | | return boost::apply_visitor( | |
| aux::read_some_visitor_ec<Mutable_Buffers>(buffers, ec) | | aux::read_some_visitor_ec<Mutable_Buffers>(buffers, ec) | |
| , m_variant | | , m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class Mutable_Buffers> | | template <class Mutable_Buffers> | |
| std::size_t read_some(Mutable_Buffers const& buffers) | | std::size_t read_some(Mutable_Buffers const& buffers) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor( | | return boost::apply_visitor( | |
| aux::read_some_visitor<Mutable_Buffers>(buffers) | | aux::read_some_visitor<Mutable_Buffers>(buffers) | |
| , m_variant | | , m_variant | |
| ); | | ); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| template <class Mutable_Buffers, class Handler> | | template <class Mutable_Buffers, class Handler> | |
| void async_read_some(Mutable_Buffers const& buffers, Handler const& han
dler) | | void async_read_some(Mutable_Buffers const& buffers, Handler const& han
dler) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::async_read_some_visitor<Mutable_Buffers, Handler>(buffers,
handler) | | aux::async_read_some_visitor<Mutable_Buffers, Handler>(buffers,
handler) | |
| , m_variant | | , m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
| skipping to change at line 611 | | skipping to change at line 625 | |
| | | | |
| template <class Handler> | | template <class Handler> | |
| void async_connect(endpoint_type const& endpoint, Handler const& handle
r) | | void async_connect(endpoint_type const& endpoint, Handler const& handle
r) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::async_connect_visitor<endpoint_type, Handler>(endpoint, ha
ndler), m_variant | | aux::async_connect_visitor<endpoint_type, Handler>(endpoint, ha
ndler), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class IO_Control_Command> | | template <class IO_Control_Command> | |
| void io_control(IO_Control_Command& ioc) | | void io_control(IO_Control_Command& ioc) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::io_control_visitor<IO_Control_Command>(ioc), m_variant | | aux::io_control_visitor<IO_Control_Command>(ioc), m_variant | |
| ); | | ); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| template <class IO_Control_Command> | | template <class IO_Control_Command> | |
| void io_control(IO_Control_Command& ioc, error_code& ec) | | void io_control(IO_Control_Command& ioc, error_code& ec) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::io_control_visitor_ec<IO_Control_Command>(ioc, ec) | | aux::io_control_visitor_ec<IO_Control_Command>(ioc, ec) | |
| , m_variant | | , m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| void bind(endpoint_type const& endpoint) | | void bind(endpoint_type const& endpoint) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor(aux::bind_visitor<endpoint_type>(endpoint), m_
variant); | | boost::apply_visitor(aux::bind_visitor<endpoint_type>(endpoint), m_
variant); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| void bind(endpoint_type const& endpoint, error_code& ec) | | void bind(endpoint_type const& endpoint, error_code& ec) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::bind_visitor_ec<endpoint_type>(endpoint, ec), m_variant | | aux::bind_visitor_ec<endpoint_type>(endpoint, ec), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| void open(protocol_type const& p) | | void open(protocol_type const& p) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor(aux::open_visitor<protocol_type>(p), m_variant
); | | boost::apply_visitor(aux::open_visitor<protocol_type>(p), m_variant
); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| void open(protocol_type const& p, error_code& ec) | | void open(protocol_type const& p, error_code& ec) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::open_visitor_ec<protocol_type>(p, ec), m_variant | | aux::open_visitor_ec<protocol_type>(p, ec), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
| bool is_open() const | | bool is_open() const | |
| { | | { | |
| return boost::apply_visitor(aux::is_open_visitor(), m_variant); | | return boost::apply_visitor(aux::is_open_visitor(), m_variant); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| void close() | | void close() | |
| { | | { | |
| if (!instantiated()) return; | | if (!instantiated()) return; | |
| boost::apply_visitor(aux::close_visitor(), m_variant); | | boost::apply_visitor(aux::close_visitor(), m_variant); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| void close(error_code& ec) | | void close(error_code& ec) | |
| { | | { | |
| if (!instantiated()) return; | | if (!instantiated()) return; | |
| boost::apply_visitor( | | boost::apply_visitor( | |
| aux::close_visitor_ec(ec), m_variant | | aux::close_visitor_ec(ec), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| std::size_t in_avail() const | | std::size_t in_avail() const | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor(aux::in_avail_visitor(), m_variant); | | return boost::apply_visitor(aux::in_avail_visitor(), m_variant); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| std::size_t in_avail(error_code& ec) const | | std::size_t in_avail(error_code& ec) const | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor( | | return boost::apply_visitor( | |
| aux::in_avail_visitor_ec(ec), m_variant | | aux::in_avail_visitor_ec(ec), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| endpoint_type remote_endpoint() const | | endpoint_type remote_endpoint() const | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor(aux::remote_endpoint_visitor<endpoint_t
ype>(), m_variant); | | return boost::apply_visitor(aux::remote_endpoint_visitor<endpoint_t
ype>(), m_variant); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| endpoint_type remote_endpoint(error_code& ec) const | | endpoint_type remote_endpoint(error_code& ec) const | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor( | | return boost::apply_visitor( | |
| aux::remote_endpoint_visitor_ec<endpoint_type>(ec), m_variant | | aux::remote_endpoint_visitor_ec<endpoint_type>(ec), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| template <class SettableSocketOption> | | template <class SettableSocketOption> | |
| void set_option(SettableSocketOption const& opt) | | void set_option(SettableSocketOption const& opt) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| boost::apply_visitor(aux::set_option_visitor<SettableSocketOption>(
opt) | | boost::apply_visitor(aux::set_option_visitor<SettableSocketOption>(
opt) | |
| , m_variant); | | , m_variant); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| template <class SettableSocketOption> | | template <class SettableSocketOption> | |
| error_code set_option(SettableSocketOption const& opt, error_code& ec) | | error_code set_option(SettableSocketOption const& opt, error_code& ec) | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor(aux::set_option_visitor_ec<SettableSock
etOption>(opt, ec) | | return boost::apply_visitor(aux::set_option_visitor_ec<SettableSock
etOption>(opt, ec) | |
| , m_variant); | | , m_variant); | |
| } | | } | |
| | | | |
|
| | | #ifndef BOOST_NO_EXCEPTIONS | |
| endpoint_type local_endpoint() const | | endpoint_type local_endpoint() const | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor(aux::local_endpoint_visitor<endpoint_ty
pe>(), m_variant); | | return boost::apply_visitor(aux::local_endpoint_visitor<endpoint_ty
pe>(), m_variant); | |
| } | | } | |
|
| | | #endif | |
| | | | |
| endpoint_type local_endpoint(error_code& ec) const | | endpoint_type local_endpoint(error_code& ec) const | |
| { | | { | |
| TORRENT_ASSERT(instantiated()); | | TORRENT_ASSERT(instantiated()); | |
| return boost::apply_visitor( | | return boost::apply_visitor( | |
| aux::local_endpoint_visitor_ec<endpoint_type>(ec), m_variant | | aux::local_endpoint_visitor_ec<endpoint_type>(ec), m_variant | |
| ); | | ); | |
| } | | } | |
| | | | |
| io_service& get_io_service() | | io_service& get_io_service() | |
| | | | |
End of changes. 37 change blocks. |
| 21 lines changed or deleted | | 49 lines changed or added | |
|