deprecated session_status and session::status() in favor of performance counters

This commit is contained in:
Arvid Norberg 2015-01-04 21:31:02 +00:00
parent 55e51ab57c
commit 35b41858cf
24 changed files with 211 additions and 138 deletions

View File

@ -1,3 +1,5 @@
* deprecated session_status and session::status() in favor of performance
counters.
* improve support for HTTP where one direction of the socket is shut down.
* remove internal fields from web_seed_entry
* separate crypto library configuration <crypto> and whether to support

View File

@ -404,7 +404,6 @@ namespace
s.get_cache_info(&ret);
return ret;
}
#endif
dict get_utp_stats(session_status const& st)
{
@ -417,7 +416,6 @@ namespace
return ret;
}
#ifndef TORRENT_NO_DEPRECATE
list get_cache_info2(lt::session& ses, sha1_hash ih)
{
std::vector<cached_piece_info> ret;
@ -503,7 +501,6 @@ void bind_session()
#ifndef TORRENT_DISABLE_DHT
void (lt::session::*start_dht0)() = &lt::session::start_dht;
void (lt::session::*start_dht1)(entry const&) = &lt::session::start_dht;
#endif
#endif
class_<session_status>("session_status")
@ -559,6 +556,7 @@ void bind_session()
.def_readonly("dht_total_allocations", &session_status::dht_total_allocations)
#endif
.add_property("utp_stats", &get_utp_stats)
#endif
;
#ifndef TORRENT_DISABLE_DHT
@ -656,7 +654,6 @@ void bind_session()
.def("outgoing_ports", &outgoing_ports)
.def("is_listening", allow_threads(&lt::session::is_listening))
.def("listen_port", allow_threads(&lt::session::listen_port))
.def("status", allow_threads(&lt::session::status))
#ifndef TORRENT_DISABLE_DHT
.def("add_dht_node", add_dht_node)
.def(
@ -678,11 +675,12 @@ void bind_session()
arg("paused") = false
)
)
#endif
#endif
#endif // TORRENT_NO_DEPRECATE
#endif // BOOST_NO_EXCEPTIONS
.def("add_feed", &add_feed)
.def("remove_torrent", allow_threads(&lt::session::remove_torrent), arg("option") = 0)
#ifndef TORRENT_NO_DEPRECATE
.def("status", allow_threads(&lt::session::status))
.def("set_settings", &lt::session::set_settings)
.def("settings", &lt::session::settings)
.def("get_settings", &session_get_settings)

View File

@ -167,7 +167,6 @@ bool print_file_progress = false;
bool show_pad_files = false;
bool show_dht_status = false;
bool sequential_download = false;
bool print_utp_stats = false;
bool print_ip = true;
bool print_as = false;
@ -1867,7 +1866,7 @@ int main(int argc, char* argv[])
if (c == 'P') show_pad_files = !show_pad_files;
if (c == 'a') print_piece_bar = !print_piece_bar;
if (c == 'g') show_dht_status = !show_dht_status;
if (c == 'u') print_utp_stats = !print_utp_stats;
if (c == 'u') ses_view.print_utp_stats(!ses_view.print_utp_stats());
if (c == 'x') print_disk_stats = !print_disk_stats;
// toggle columns
if (c == '1') print_ip = !print_ip;
@ -1940,8 +1939,6 @@ int main(int argc, char* argv[])
}
alerts.clear();
session_status sess_stat = ses.status();
std::string out;
char str[500];
@ -1956,6 +1953,8 @@ int main(int argc, char* argv[])
cache_status cs;
ses.get_cache_info(&cs, h, cache_flags);
// TODO: 3 introce some reasonable way of getting DHT stats
/*
#ifndef TORRENT_DISABLE_DHT
if (show_dht_status)
{
@ -2006,15 +2005,7 @@ int main(int argc, char* argv[])
}
}
#endif
if (print_utp_stats)
{
snprintf(str, sizeof(str), "uTP idle: %d syn: %d est: %d fin: %d wait: %d\n"
, sess_stat.utp_stats.num_idle, sess_stat.utp_stats.num_syn_sent
, sess_stat.utp_stats.num_connected, sess_stat.utp_stats.num_fin_sent
, sess_stat.utp_stats.num_close_wait);
out += str;
}
*/
if (h.is_valid())
{
torrent_status const& s = view.get_active_torrent();

View File

@ -2,6 +2,7 @@
#include "print.hpp"
session_view::session_view()
: m_print_utp_stats(false)
{
using libtorrent::find_metric_idx;
@ -37,6 +38,12 @@ session_view::session_view()
m_mfu_ghost_idx = find_metric_idx("disk.arc_mfu_ghost_size");
m_mru_size_idx = find_metric_idx("disk.arc_mru_size");
m_mru_ghost_idx = find_metric_idx("disk.arc_mru_ghost_size");
m_utp_idle = find_metric_idx("utp.num_utp_idle");
m_utp_syn_sent = find_metric_idx("utp.num_utp_syn_sent");
m_utp_connected = find_metric_idx("utp.num_utp_connected");
m_utp_fin_sent = find_metric_idx("utp.num_utp_fin_sent");
m_utp_close_wait = find_metric_idx("utp.num_utp_close_wait");
}
void session_view::set_pos(int pos)
@ -48,7 +55,7 @@ int session_view::pos() const { return m_position; }
int session_view::height() const
{
return 3;
return 3 + m_print_utp_stats;
}
void session_view::render()
@ -161,6 +168,18 @@ void session_view::render()
pos += snprintf(str + pos, sizeof(str) - pos, "\x1b[K");
set_cursor_pos(0, y++);
print(str);
if (m_print_utp_stats)
{
snprintf(str, sizeof(str), "uTP idle: %d syn: %d est: %d fin: %d wait: %d\x1b[K"
, int(m_cnt[0][m_utp_idle])
, int(m_cnt[0][m_utp_syn_sent])
, int(m_cnt[0][m_utp_connected])
, int(m_cnt[0][m_utp_fin_sent])
, int(m_cnt[0][m_utp_close_wait]));
set_cursor_pos(0, y++);
print(str);
}
}
void session_view::update_counters(std::vector<boost::uint64_t>& stats_counters

View File

@ -17,6 +17,9 @@ struct session_view
void render();
void print_utp_stats(bool p) { m_print_utp_stats = p; }
bool print_utp_stats() const { return m_print_utp_stats; }
void update_counters(std::vector<boost::uint64_t>& stats_counters
, boost::uint64_t t);
@ -33,6 +36,8 @@ private:
// respectively. The timestamps are microseconds since session start
boost::uint64_t m_timestamp[2];
bool m_print_utp_stats;
int m_queued_bytes_idx;
int m_wasted_bytes_idx;
int m_failed_bytes_idx;
@ -58,6 +63,12 @@ private:
int m_mfu_ghost_idx;
int m_mru_size_idx;
int m_mru_ghost_idx;
int m_utp_idle;
int m_utp_syn_sent;
int m_utp_connected;
int m_utp_fin_sent;
int m_utp_close_wait;
};
#endif

View File

@ -470,7 +470,10 @@ namespace libtorrent
m_optimistic_unchoke_time_scaler = 0;
}
#ifndef TORRENT_NO_DEPRECATE
session_status status() const;
#endif
void set_peer_id(peer_id const& id);
void set_key(int key);
address listen_address() const;
@ -875,6 +878,8 @@ namespace libtorrent
// the number of unchoked peers as set by the auto-unchoker
// this should always be >= m_max_uploads
// TODO: 3 this member could probably be removed, now that we have
// a performance counter gauge for it
int m_allowed_upload_slots;
// this is initialized to the unchoke_interval

View File

@ -49,7 +49,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/kademlia/dos_blocker.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/session_status.hpp"
#include "libtorrent/udp_socket.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/thread.hpp"
@ -60,6 +59,9 @@ namespace libtorrent
namespace aux { struct session_impl; }
struct lazy_entry;
struct counters;
#ifndef TORRENT_NO_DEPRECATE
struct session_status;
#endif
}
namespace libtorrent { namespace dht
@ -112,7 +114,10 @@ namespace libtorrent { namespace dht
void put_item(char const* key
, boost::function<void(item&)> cb, std::string salt = std::string());
#ifndef TORRENT_NO_DEPRECATE
void dht_status(session_status& s);
#endif
void network_stats(int& sent, int& received);
// translate bittorrent kademlia message into the generic kademlia message

View File

@ -275,7 +275,9 @@ public:
m_running_requests.erase(a);
}
#ifndef TORRENT_NO_DEPRECATE
void status(libtorrent::session_status& s);
#endif
libtorrent::dht_settings const& settings() const { return m_settings; }
counters& stats_counters() const { return m_counters; }

View File

@ -51,10 +51,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <libtorrent/time.hpp>
#include <boost/unordered_set.hpp>
#ifndef TORRENT_NO_DEPRECATE
namespace libtorrent
{
struct session_status;
}
#endif
namespace libtorrent { namespace dht
{
@ -90,7 +92,9 @@ public:
routing_table(node_id const& id, int bucket_size
, dht_settings const& settings);
#ifndef TORRENT_NO_DEPRECATE
void status(session_status& s) const;
#endif
void node_failed(node_id const& id, udp::endpoint const& ep);

View File

@ -230,7 +230,7 @@ namespace libtorrent
sent_dht_bytes,
recv_dht_bytes,
// uTP counters
// uTP counters.
utp_packet_loss,
utp_timeout,
utp_packets_in,
@ -408,6 +408,16 @@ namespace libtorrent
limiter_up_bytes,
limiter_down_bytes,
// the number of uTP connections in each respective state
// these must be defined in the same order as the state_t enum
// in utp_stream
num_utp_idle,
num_utp_syn_sent,
num_utp_connected,
num_utp_fin_sent,
num_utp_close_wait,
num_utp_deleted,
num_counters,
num_gauge_counters = num_counters - num_stats_counters
};

View File

@ -49,7 +49,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/entry.hpp"
#include "libtorrent/session_status.hpp"
#include "libtorrent/version.hpp"
#include "libtorrent/fingerprint.hpp"
#include "libtorrent/disk_io_thread.hpp"
@ -85,6 +84,10 @@ namespace libtorrent
class connection_queue;
class alert;
#ifndef TORRENT_NO_DEPRECATE
struct session_status;
#endif
// describes one statistics metric from the session. For more information,
// see the session-statistics_ section.
struct TORRENT_EXPORT stats_metric
@ -484,16 +487,18 @@ namespace libtorrent
// void fun(sha1_hash const& info_hash, std::vector<char>& buf, error_code& ec);
void set_load_function(user_load_function_t fun);
#ifndef TORRENT_NO_DEPRECATE
// deprecated in libtorrent 1.1, use performance_counters instead
// returns session wide-statistics and status. For more information, see
// the ``session_status`` struct.
session_status status() const;
#ifndef TORRENT_NO_DEPRECATE
// deprecated in aio branch
TORRENT_DEPRECATED_PREFIX
session_status status() const TORRENT_DEPRECATED;
// deprecated in libtorrent 1.1
// fills out the supplied vector with information for each piece that is
// currently in the disk cache for the torrent with the specified
// info-hash (``ih``).
TORRENT_DEPRECATED_PREFIX
void get_cache_info(sha1_hash const& ih
, std::vector<cached_piece_info>& ret) const TORRENT_DEPRECATED;

View File

@ -84,6 +84,7 @@ namespace libtorrent
int first_timeout;
};
// TODO: 3 add accessors tp query the DHT state (post the result as an alert)
// holds dht routing table stats
struct TORRENT_EXPORT dht_routing_bucket
{
@ -92,13 +93,14 @@ namespace libtorrent
int num_nodes;
int num_replacements;
#ifndef TORRENT_NO_DEPRECATE
// number of seconds since last activity
int last_active;
#endif
};
#ifndef TORRENT_NO_DEPRECATE
// holds counters and gauges for the uTP sockets
// deprecated in 1.1 in favor of session_stats counters, which is a more
// flexible, extensible and perfromant mechanism for stats.
struct TORRENT_EXPORT utp_status
{
// gauges. These are snapshots of the number of
@ -109,10 +111,6 @@ namespace libtorrent
int num_fin_sent;
int num_close_wait;
#ifndef TORRENT_NO_DEPRECATE
// deprecated in libtorrent 1.1
// use session_stats/performance_counters instead
// counters
// These are monotonically increasing
// and cumulative counters for their respective event.
boost::uint64_t packet_loss;
@ -127,10 +125,11 @@ namespace libtorrent
boost::uint64_t payload_pkts_out;
boost::uint64_t invalid_pkts_in;
boost::uint64_t redundant_pkts_in;
#endif
};
// contains session wide state and counters
// deprecated in 1.1 in favor of session_stats counters, which is a more
// flexible, extensible and perfromant mechanism for stats.
struct TORRENT_EXPORT session_status
{
// false as long as no incoming connections have been
@ -269,6 +268,7 @@ namespace libtorrent
int num_torrents;
int num_paused_torrents;
};
#endif // TORRENT_NO_DEPRECATE
}

View File

@ -55,8 +55,6 @@ namespace libtorrent
, counters& cnt, void* ssl_context, incoming_utp_callback_t cb);
~utp_socket_manager();
void get_status(utp_status& s) const;
// return false if this is not a uTP packet
virtual bool incoming_packet(error_code const& ec, udp::endpoint const& ep
, char const* p, int size);
@ -100,7 +98,7 @@ namespace libtorrent
// used to keep stats of uTP events
// the counter is the enum from ``counters``.
void inc_stats_counter(int counter);
void inc_stats_counter(int counter, int delta = 1);
private:
udp_socket& m_sock;

View File

@ -259,10 +259,12 @@ namespace libtorrent { namespace dht
m_host_resolver.cancel();
}
#ifndef TORRENT_NO_DEPRECATE
void dht_tracker::dht_status(session_status& s)
{
m_dht.status(s);
}
#endif
void dht_tracker::network_stats(int& sent, int& received)
{

View File

@ -565,6 +565,7 @@ time_duration node_impl::connection_timeout()
return d;
}
#ifndef TORRENT_NO_DEPRECATE
void node_impl::status(session_status& s)
{
mutex_t::scoped_lock l(m_mutex);
@ -581,6 +582,7 @@ void node_impl::status(session_status& s)
(*i)->status(l);
}
}
#endif
void node_impl::lookup_peers(sha1_hash const& info_hash, entry& reply
, bool noseed, bool scrape) const

View File

@ -93,6 +93,7 @@ int routing_table::bucket_limit(int bucket) const
return m_bucket_size;
}
#ifndef TORRENT_NO_DEPRECATE
void routing_table::status(session_status& s) const
{
int ignore;
@ -111,6 +112,7 @@ void routing_table::status(session_status& s) const
s.dht_routing_table.push_back(b);
}
}
#endif
boost::tuple<int, int, int> routing_table::size() const
{

View File

@ -721,11 +721,6 @@ namespace libtorrent
return TORRENT_SYNC_CALL_RET(unsigned short, ssl_listen_port);
}
session_status session::status() const
{
return TORRENT_SYNC_CALL_RET(session_status, status);
}
void session::pause()
{
TORRENT_ASYNC_CALL(pause);
@ -742,6 +737,11 @@ namespace libtorrent
}
#ifndef TORRENT_NO_DEPRECATE
session_status session::status() const
{
return TORRENT_SYNC_CALL_RET(session_status, status);
}
void session::get_cache_info(sha1_hash const& ih
, std::vector<cached_piece_info>& ret) const
{

View File

@ -3918,6 +3918,8 @@ retry:
m_allowed_upload_slots = unchoke_sort(peers, max_upload_rate
, unchoke_interval, m_settings);
m_stats_counters.set_value(counters::num_unchoke_slots
, m_allowed_upload_slots);
int num_opt_unchoke = m_settings.get_int(settings_pack::num_optimistic_unchoke_slots);
if (num_opt_unchoke == 0) num_opt_unchoke = (std::max)(1, m_allowed_upload_slots / 5);
@ -5218,8 +5220,7 @@ retry:
}
}
// TODO: 3 deprecate this function. All of this functionality should be
// exposed as performance counters
#ifndef TORRENT_NO_DEPRECATE
session_status session_impl::status() const
{
// INVARIANT_CHECK;
@ -5229,24 +5230,36 @@ retry:
s.optimistic_unchoke_counter = m_optimistic_unchoke_time_scaler;
s.unchoke_counter = m_unchoke_time_scaler;
s.num_peers = int(m_connections.size());
s.num_dead_peers = int(m_undead_peers.size());
s.num_unchoked = m_stats_counters[counters::num_peers_up_unchoked_all];
s.allowed_upload_slots = m_allowed_upload_slots;
s.num_torrents = m_torrents.size();
// only non-paused torrents want tick
s.num_paused_torrents = m_torrents.size() - m_torrent_lists[torrent_want_tick].size();
s.num_peers = m_stats_counters[counters::num_peers_connected];
s.num_unchoked = m_stats_counters[counters::num_peers_up_unchoked_all];
s.allowed_upload_slots = m_stats_counters[counters::num_unchoke_slots];
s.num_torrents
= m_stats_counters[counters::num_checking_torrents]
+ m_stats_counters[counters::num_stopped_torrents]
+ m_stats_counters[counters::num_queued_seeding_torrents]
+ m_stats_counters[counters::num_queued_download_torrents]
+ m_stats_counters[counters::num_upload_only_torrents]
+ m_stats_counters[counters::num_downloading_torrents]
+ m_stats_counters[counters::num_seeding_torrents]
+ m_stats_counters[counters::num_error_torrents];
s.num_paused_torrents
= m_stats_counters[counters::num_stopped_torrents]
+ m_stats_counters[counters::num_error_torrents]
+ m_stats_counters[counters::num_queued_seeding_torrents]
+ m_stats_counters[counters::num_queued_download_torrents];
s.total_redundant_bytes = m_stats_counters[counters::recv_redundant_bytes];
s.total_failed_bytes = m_stats_counters[counters::recv_failed_bytes];
s.up_bandwidth_queue = m_upload_rate.queue_size();
s.down_bandwidth_queue = m_download_rate.queue_size();
s.up_bandwidth_queue = m_stats_counters[counters::limiter_up_queue];
s.down_bandwidth_queue = m_stats_counters[counters::limiter_down_queue];
s.up_bandwidth_bytes_queue = int(m_upload_rate.queued_bytes());
s.down_bandwidth_bytes_queue = int(m_download_rate.queued_bytes());
s.up_bandwidth_bytes_queue = m_stats_counters[counters::limiter_up_bytes];
s.down_bandwidth_bytes_queue = m_stats_counters[counters::limiter_down_bytes];
s.disk_write_queue = m_stats_counters[counters::num_peers_down_disk];
s.disk_read_queue = m_stats_counters[counters::num_peers_up_disk];
@ -5288,6 +5301,7 @@ retry:
#ifndef TORRENT_DISABLE_DHT
if (m_dht)
{
// TODO: 3 replace this call with session_stats
m_dht->dht_status(s);
}
else
@ -5300,7 +5314,24 @@ retry:
s.dht_total_allocations = 0;
}
m_utp_socket_manager.get_status(s.utp_stats);
s.utp_stats.packet_loss = m_stats_counters[counters::utp_packet_loss];
s.utp_stats.timeout = m_stats_counters[counters::utp_timeout];
s.utp_stats.packets_in = m_stats_counters[counters::utp_packets_in];
s.utp_stats.packets_out = m_stats_counters[counters::utp_packets_out];
s.utp_stats.fast_retransmit = m_stats_counters[counters::utp_fast_retransmit];
s.utp_stats.packet_resend = m_stats_counters[counters::utp_packet_resend];
s.utp_stats.samples_above_target = m_stats_counters[counters::utp_samples_above_target];
s.utp_stats.samples_below_target = m_stats_counters[counters::utp_samples_below_target];
s.utp_stats.payload_pkts_in = m_stats_counters[counters::utp_payload_pkts_in];
s.utp_stats.payload_pkts_out = m_stats_counters[counters::utp_payload_pkts_out];
s.utp_stats.invalid_pkts_in = m_stats_counters[counters::utp_invalid_pkts_in];
s.utp_stats.redundant_pkts_in = m_stats_counters[counters::utp_redundant_pkts_in];
s.utp_stats.num_idle = m_stats_counters[counters::num_utp_idle];
s.utp_stats.num_syn_sent = m_stats_counters[counters::num_utp_syn_sent];
s.utp_stats.num_connected = m_stats_counters[counters::num_utp_connected];
s.utp_stats.num_fin_sent = m_stats_counters[counters::num_utp_fin_sent];
s.utp_stats.num_close_wait = m_stats_counters[counters::num_utp_close_wait];
// this loop is potentially expensive. It could be optimized by
// simply keeping a global counter
@ -5315,6 +5346,7 @@ retry:
return s;
}
#endif // TORRENT_NO_DEPRECATE
#ifndef TORRENT_DISABLE_DHT

View File

@ -458,6 +458,13 @@ namespace libtorrent
METRIC(utp, utp_invalid_pkts_in)
METRIC(utp, utp_redundant_pkts_in)
// the number of uTP sockets in each respective state
METRIC(utp, num_utp_idle)
METRIC(utp, num_utp_syn_sent)
METRIC(utp, num_utp_connected)
METRIC(utp, num_utp_fin_sent)
METRIC(utp, num_utp_close_wait)
// the buffer sizes accepted by
// socket send and receive calls respectively.
// The larger the buffers are, the more efficient,

View File

@ -70,45 +70,6 @@ namespace libtorrent
}
}
void utp_socket_manager::get_status(utp_status& s) const
{
s.num_idle = 0;
s.num_syn_sent = 0;
s.num_connected = 0;
s.num_fin_sent = 0;
s.num_close_wait = 0;
#ifndef TORRENT_NO_DEPRECATE
s.packet_loss = m_counters[counters::utp_packet_loss];
s.timeout = m_counters[counters::utp_timeout];
s.packets_in = m_counters[counters::utp_packets_in];
s.packets_out = m_counters[counters::utp_packets_out];
s.fast_retransmit = m_counters[counters::utp_fast_retransmit];
s.packet_resend = m_counters[counters::utp_packet_resend];
s.samples_above_target = m_counters[counters::utp_samples_above_target];
s.samples_below_target = m_counters[counters::utp_samples_below_target];
s.payload_pkts_in = m_counters[counters::utp_payload_pkts_in];
s.payload_pkts_out = m_counters[counters::utp_payload_pkts_out];
s.invalid_pkts_in = m_counters[counters::utp_invalid_pkts_in];
s.redundant_pkts_in = m_counters[counters::utp_redundant_pkts_in];
#endif
for (socket_map_t::const_iterator i = m_utp_sockets.begin()
, end(m_utp_sockets.end()); i != end; ++i)
{
int state = utp_socket_state(i->second);
switch (state)
{
case 0: ++s.num_idle; break;
case 1: ++s.num_syn_sent; break;
case 2: ++s.num_connected; break;
case 3: ++s.num_fin_sent; break;
case 4: ++s.num_close_wait; break;
case 5: ++s.num_close_wait; break;
}
}
}
void utp_socket_manager::tick(ptime now)
{
for (socket_map_t::iterator i = m_utp_sockets.begin()
@ -465,11 +426,13 @@ namespace libtorrent
m_sock_buf_size = size;
}
void utp_socket_manager::inc_stats_counter(int counter)
void utp_socket_manager::inc_stats_counter(int counter, int delta)
{
TORRENT_ASSERT(counter >= counters::utp_packet_loss);
TORRENT_ASSERT(counter <= counters::utp_redundant_pkts_in);
m_counters.inc_stats_counter(counter);
TORRENT_ASSERT((counter >= counters::utp_packet_loss
&& counter <= counters::utp_redundant_pkts_in)
|| (counter >= counters::num_utp_idle
&& counter <= counters::num_utp_deleted));
m_counters.inc_stats_counter(counter, delta);
}
utp_socket_impl* utp_socket_manager::new_utp_socket(utp_stream* str)

View File

@ -279,6 +279,7 @@ struct utp_socket_impl
, m_subscribe_drained(false)
, m_stalled(false)
{
m_sm->inc_stats_counter(counters::num_utp_idle);
TORRENT_ASSERT(m_userdata);
for (int i = 0; i != num_delay_hist; ++i)
m_delay_sample_hist[i] = (std::numeric_limits<boost::uint32_t>::max)();
@ -336,6 +337,17 @@ struct utp_socket_impl
void update_mtu_limits();
void experienced_loss(int seq_nr);
void set_state(int s);
private:
// non-copyable
utp_socket_impl(utp_socket_impl const&);
utp_socket_impl const& operator=(utp_socket_impl const&);
// TODO: 2 it would be nice if not everything would have to be public here
public:
void check_receive_buffers() const;
#if TORRENT_USE_INVARIANT_CHECKS
@ -569,6 +581,8 @@ struct utp_socket_impl
// this affects the packet timeout time
boost::uint8_t m_num_timeouts;
// it's important that these match the enums in performance_counters for
// num_utp_idle etc.
enum state_t {
// not yet connected
UTP_STATE_NONE,
@ -1109,6 +1123,8 @@ utp_socket_impl::~utp_socket_impl()
TORRENT_ASSERT(!m_attached);
TORRENT_ASSERT(!m_deferred_ack);
m_sm->inc_stats_counter(counters::num_utp_idle + m_state, -1);
UTP_LOGV("%8p: destroying utp socket state\n", this);
// free any buffers we're holding
@ -1224,7 +1240,7 @@ bool utp_socket_impl::destroy()
|| m_state == UTP_STATE_NONE
|| m_state == UTP_STATE_SYN_SENT) && cancelled)
{
m_state = UTP_STATE_DELETE;
set_state(UTP_STATE_DELETE);
#if TORRENT_UTP_LOG
UTP_LOGV("%8p: state:%s\n", this, socket_state_names[m_state]);
#endif
@ -1304,7 +1320,7 @@ void utp_socket_impl::send_syn()
{
free(p);
m_error = ec;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return;
}
@ -1320,7 +1336,7 @@ void utp_socket_impl::send_syn()
m_seq_nr = (m_seq_nr + 1) & ACK_MASK;
TORRENT_ASSERT(!m_error);
m_state = UTP_STATE_SYN_SENT;
set_state(UTP_STATE_SYN_SENT);
#if TORRENT_UTP_LOG
UTP_LOGV("%8p: state:%s\n", this, socket_state_names[m_state]);
#endif
@ -1349,7 +1365,7 @@ void utp_socket_impl::send_fin()
// unless there was an error, we're now
// in FIN-SENT state
if (!m_error)
m_state = UTP_STATE_FIN_SENT;
set_state(UTP_STATE_FIN_SENT);
#if TORRENT_UTP_LOG
UTP_LOGV("%8p: state:%s\n", this, socket_state_names[m_state]);
@ -1955,7 +1971,7 @@ bool utp_socket_impl::send_pkt(int flags)
{
TORRENT_ASSERT(stack_alloced != bool(payload_size));
m_error = ec;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return false;
}
@ -2134,7 +2150,7 @@ bool utp_socket_impl::resend_packet(packet* p, bool fast_resend)
else if (ec)
{
m_error = ec;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return false;
}
@ -2179,6 +2195,15 @@ void utp_socket_impl::experienced_loss(int seq_nr)
m_sm->inc_stats_counter(counters::utp_packet_loss);
}
void utp_socket_impl::set_state(int s)
{
if (s == m_state) return;
m_sm->inc_stats_counter(counters::num_utp_idle + m_state, -1);
m_state = s;
m_sm->inc_stats_counter(counters::num_utp_idle + m_state, 1);
}
void utp_socket_impl::maybe_inc_acked_seq_nr()
{
INVARIANT_CHECK;
@ -2472,7 +2497,7 @@ bool utp_socket_impl::test_socket_state()
if (cancel_handlers(m_error, true))
{
m_state = UTP_STATE_DELETE;
set_state(UTP_STATE_DELETE);
#if TORRENT_UTP_LOG
UTP_LOGV("%8p: state:%s\n", this, socket_state_names[m_state]);
#endif
@ -2695,7 +2720,7 @@ bool utp_socket_impl::incoming_packet(boost::uint8_t const* buf, int size
}
UTP_LOGV("%8p: incoming packet type:RESET\n", this);
m_error = asio::error::connection_reset;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return true;
}
@ -2896,7 +2921,7 @@ bool utp_socket_impl::incoming_packet(boost::uint8_t const* buf, int size
{
// if we're in state_none, the only thing
// we accept are SYN packets.
m_state = UTP_STATE_CONNECTED;
set_state(UTP_STATE_CONNECTED);
m_remote_address = ep.address();
m_port = ep.port();
@ -2944,7 +2969,7 @@ bool utp_socket_impl::incoming_packet(boost::uint8_t const* buf, int size
}
TORRENT_ASSERT(!m_error);
m_state = UTP_STATE_CONNECTED;
set_state(UTP_STATE_CONNECTED);
#if TORRENT_UTP_LOG
UTP_LOGV("%8p: state:%s\n", this, socket_state_names[m_state]);
#endif
@ -3187,14 +3212,14 @@ bool utp_socket_impl::incoming_packet(boost::uint8_t const* buf, int size
{
UTP_LOGV("%8p: close initiated here, delete socket\n", this);
m_error = asio::error::eof;
m_state = UTP_STATE_DELETE;
set_state(UTP_STATE_DELETE);
test_socket_state();
}
else
{
UTP_LOGV("%8p: closing socket\n", this);
m_error = asio::error::eof;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
}
}
@ -3386,7 +3411,7 @@ void utp_socket_impl::tick(ptime now)
{
// the connection is dead
m_error = asio::error::timed_out;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return;
}
@ -3471,7 +3496,7 @@ void utp_socket_impl::tick(ptime now)
// the connection is dead
m_error = asio::error::timed_out;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return;
}
@ -3493,7 +3518,7 @@ void utp_socket_impl::tick(ptime now)
{
// the connection is dead
m_error = asio::error::eof;
m_state = UTP_STATE_ERROR_WAIT;
set_state(UTP_STATE_ERROR_WAIT);
test_socket_state();
return;
}

View File

@ -41,7 +41,6 @@ namespace libtorrent
{
class alert;
struct add_torrent_params;
struct session_status;
}
int EXPORT print_failures();

View File

@ -94,18 +94,19 @@ void test_swarm()
boost::tie(tor1, tor2, tor3) = setup_transfer(&ses1, &ses2, &ses3, true, false, true, "_unchoke");
session_status st = ses1.status();
fprintf(stderr, "st.allowed_upload_slots: %d\n", st.allowed_upload_slots);
TEST_EQUAL(st.allowed_upload_slots, 1);
std::map<std::string, boost::uint64_t> cnt = get_counters(ses1);
fprintf(stderr, "allowed_upload_slots: %d\n", int(cnt["ses.num_unchoke_slots"]));
TEST_EQUAL(cnt["ses.num_unchoke_slots"], 1);
for (int i = 0; i < 200; ++i)
{
print_alerts(ses1, "ses1");
print_alerts(ses2, "ses2");
print_alerts(ses3, "ses3");
st = ses1.status();
fprintf(stderr, "allowed unchoked: %d\n", st.allowed_upload_slots);
if (st.allowed_upload_slots >= 2) break;
cnt = get_counters(ses1);
fprintf(stderr, "allowed unchoked: %d\n", int(cnt["ses.num_unchoke_slots"]));
if (cnt["ses.num_unchoke_slots"] >= 2) break;
torrent_status st1 = tor1.status();
torrent_status st2 = tor2.status();
@ -116,7 +117,7 @@ void test_swarm()
test_sleep(100);
}
TEST_CHECK(st.allowed_upload_slots >= 2);
TEST_CHECK(cnt["ses.num_unchoke_slots"] >= 2);
// make sure the files are deleted
ses1.remove_torrent(tor1, lt::session::delete_files);

View File

@ -151,9 +151,6 @@ void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_fil
const boost::int64_t total_size = torrent_file->total_size();
float rate_sum = 0.f;
float ses_rate_sum = 0.f;
file_storage const& fs = torrent_file->files();
int pad_file_size = 0;
for (int i = 0; i < fs.num_files(); ++i)
@ -163,16 +160,15 @@ void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_fil
}
peer_disconnects = 0;
std::map<std::string, boost::uint64_t> cnt = get_counters(ses);
for (int i = 0; i < 40; ++i)
{
torrent_status s = th.status();
session_status ss = ses.status();
rate_sum += s.download_payload_rate;
ses_rate_sum += ss.payload_download_rate;
cnt = get_counters(ses);
print_ses_rate(i / 10.f, &s, NULL);
print_alerts(ses, " >> ses", test_ban, false, false, &on_alert);
if (test_ban && th.url_seeds().empty() && th.http_seeds().empty())
@ -186,7 +182,7 @@ void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_fil
{
fprintf(stderr, "SEEDING\n");
fprintf(stderr, "session.payload: %d session.redundant: %d\n"
, int(ses.status().total_payload_download), int(ses.status().total_redundant_bytes));
, int(cnt["net.recv_payload_bytes"]), int(cnt["net.recv_redundant_bytes"]));
fprintf(stderr, "torrent.payload: %d torrent.redundant: %d\n"
, int(s.total_payload_download), int(s.total_redundant_bytes));
@ -209,7 +205,7 @@ void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_fil
// the url seed (i.e. banned it)
TEST_CHECK(!test_ban || (th.url_seeds().empty() && th.http_seeds().empty()));
std::map<std::string, boost::uint64_t> cnt = get_counters(ses);
cnt = get_counters(ses);
// if the web seed senr corrupt data and we banned it, we probably didn't
// end up using all the cache anyway
@ -240,17 +236,11 @@ void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_fil
std::cerr << "total_size: " << total_size
<< " read cache size: " << cnt["disk.disk_blocks_in_use"]
<< " total used buffer: " << cnt["disk.disk_blocks_in_use"]
<< " rate_sum: " << rate_sum
<< " session_rate_sum: " << ses_rate_sum
<< " session total download: " << ses.status().total_payload_download
<< " session total download: " << cnt["net.recv_payload_bytes"]
<< " torrent total download: " << th.status().total_payload_download
<< " redundant: " << th.status().total_redundant_bytes
<< std::endl;
// the rates for each second should sum up to the total, with a 10% error margin
// TEST_CHECK(fabs(rate_sum - total_size) < total_size * .1f);
// TEST_CHECK(fabs(ses_rate_sum - total_size) < total_size * .1f);
// if test_ban is true, we're not supposed to have completed the download
// otherwise, we are supposed to have
TEST_CHECK(th.status().is_seeding == !test_ban);