landed alert_queue feature branch into trunk

This commit is contained in:
Arvid Norberg 2015-04-03 20:15:48 +00:00
parent 7118387926
commit 013ed36f09
61 changed files with 2902 additions and 1393 deletions

View File

@ -195,7 +195,10 @@ void bind_alert()
class_<tracker_alert, bases<torrent_alert>, noncopyable>(
"tracker_alert", no_init)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("url", &tracker_alert::url)
#endif
.def("tracker_url", &tracker_alert::tracker_url)
;
class_<torrent_added_alert, bases<torrent_alert>, noncopyable>(
@ -221,7 +224,10 @@ void bind_alert()
;
class_<tracker_error_alert, bases<tracker_alert>, noncopyable>(
"tracker_error_alert", no_init)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &tracker_error_alert::msg)
#endif
.def_readonly("error_message", &tracker_error_alert::error_message)
.def_readonly("times_in_row", &tracker_error_alert::times_in_row)
.def_readonly("status_code", &tracker_error_alert::status_code)
.def_readonly("error", &tracker_error_alert::error)
@ -295,7 +301,10 @@ void bind_alert()
class_<storage_moved_alert, bases<torrent_alert>, noncopyable>(
"storage_moved_alert", no_init)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("path", &storage_moved_alert::path)
#endif
.def("storage_path", &storage_moved_alert::storage_path)
;
class_<storage_moved_failed_alert, bases<torrent_alert>, noncopyable>(
@ -316,15 +325,19 @@ void bind_alert()
class_<url_seed_alert, bases<torrent_alert>, noncopyable>(
"url_seed_alert", no_init)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("url", &url_seed_alert::url)
.def_readonly("msg", &url_seed_alert::msg)
#endif
.def("server_url", &url_seed_alert::server_url)
;
class_<file_error_alert, bases<torrent_alert>, noncopyable>(
"file_error_alert", no_init)
.def_readonly("file", &file_error_alert::file)
.def_readonly("error", &file_error_alert::error)
.def("filename", &file_error_alert::filename)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("file", &file_error_alert::file)
.def_readonly("msg", &file_error_alert::msg)
#endif
;
@ -337,7 +350,10 @@ void bind_alert()
class_<listen_failed_alert, bases<alert>, noncopyable>(
"listen_failed_alert", no_init)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("interface", &listen_failed_alert::interface)
#endif
.def("listen_interface", &listen_failed_alert::listen_interface)
.def_readonly("error", &listen_failed_alert::error)
.def_readonly("operation", &listen_failed_alert::operation)
.def_readonly("sock_type", &listen_failed_alert::sock_type)
@ -399,7 +415,10 @@ void bind_alert()
class_<scrape_failed_alert, bases<tracker_alert>, noncopyable>(
"scrape_failed_alert", no_init)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("msg", &scrape_failed_alert::msg)
#endif
.def("error_message", &scrape_failed_alert::error_message)
;
class_<udp_error_alert, bases<alert>, noncopyable>(
@ -426,7 +445,10 @@ void bind_alert()
class_<file_renamed_alert, bases<torrent_alert>, noncopyable>(
"file_renamed_alert", no_init)
.def_readonly("index", &file_renamed_alert::index)
#ifndef TORRENT_NO_DEPRECATE
.def_readonly("name", &file_renamed_alert::name)
#endif
.def("new_name", &file_renamed_alert::new_name)
;
class_<file_rename_failed_alert, bases<torrent_alert>, noncopyable>(
@ -608,17 +630,17 @@ void bind_alert()
class_<log_alert, bases<alert>, noncopyable>(
"log_alert", no_init)
.def_readonly("msg", &log_alert::msg)
.def("msg", &log_alert::msg)
;
class_<torrent_log_alert, bases<torrent_alert>, noncopyable>(
"torrent_log_alert", no_init)
.def_readonly("msg", &torrent_log_alert::msg)
.def("msg", &torrent_log_alert::msg)
;
class_<peer_log_alert, bases<peer_alert>, noncopyable>(
"peer_log_alert", no_init)
.def_readonly("msg", &peer_log_alert::msg)
.def("msg", &peer_log_alert::msg)
;
class_<lsd_error_alert, bases<alert>, noncopyable>(

View File

@ -273,6 +273,7 @@ namespace
s.async_add_torrent(p);
}
#ifndef TORRENT_NO_DEPRECATE
void dict_to_feed_settings(dict params, feed_settings& feed)
{
if (params.has_key("auto_download"))
@ -354,7 +355,6 @@ namespace
return ret;
}
#ifndef TORRENT_NO_DEPRECATE
void start_natpmp(lt::session& s)
{
allow_threading_guard guard;
@ -452,6 +452,7 @@ namespace
return e;
}
#ifndef TORRENT_NO_DEPRECATE
object pop_alert(lt::session& ses)
{
std::auto_ptr<alert> a;
@ -462,17 +463,18 @@ namespace
return object(boost::shared_ptr<alert>(a.release()));
}
#endif
list pop_alerts(lt::session& ses)
{
std::deque<alert*> alerts;
std::vector<alert*> alerts;
{
allow_threading_guard guard;
ses.pop_alerts(&alerts);
}
list ret;
for (std::deque<alert*>::iterator i = alerts.begin()
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
ret.append(boost::shared_ptr<alert>(*i));
@ -677,9 +679,9 @@ void bind_session()
)
#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("add_feed", &add_feed)
.def("status", allow_threads(&lt::session::status))
.def("set_settings", &lt::session::set_settings)
.def("settings", &lt::session::settings)
@ -697,11 +699,11 @@ void bind_session()
#endif
.def("load_state", &load_state)
.def("save_state", &save_state, (arg("entry"), arg("flags") = 0xffffffff))
.def("pop_alert", &pop_alert)
.def("pop_alerts", &pop_alerts)
.def("wait_for_alert", &wait_for_alert, return_internal_reference<>())
.def("add_extension", &add_extension)
#ifndef TORRENT_NO_DEPRECATE
.def("pop_alert", &pop_alert)
#if TORRENT_USE_I2P
.def("set_i2p_proxy", allow_threads(&lt::session::set_i2p_proxy))
.def("i2p_proxy", allow_threads(&lt::session::i2p_proxy))
@ -789,7 +791,6 @@ void bind_session()
.value("listen_reuse_address", lt::session::listen_reuse_address)
.value("listen_no_system_port", lt::session::listen_no_system_port)
;
#endif
class_<feed_handle>("feed_handle")
.def("update_feed", &feed_handle::update_feed)
@ -797,6 +798,7 @@ void bind_session()
.def("set_settings", &set_feed_settings)
.def("settings", &get_feed_settings)
;
#endif
register_ptr_to_python<std::auto_ptr<alert> >();

View File

@ -91,7 +91,6 @@ category_mapping = {
'broadcast_socket.hpp': 'Network',
'socket.hpp': 'Network',
'socket_io.hpp': 'Network',
'rss.hpp': 'RSS',
'bitfield.hpp': 'Utility',
'sha1_hash.hpp': 'Utility',
'hasher.hpp': 'Utility',

View File

@ -13,7 +13,6 @@ REFERENCE_TARGETS = \
reference-Utility \
reference-Bencoding \
reference-Alerts \
reference-RSS \
reference-Filter \
reference-Settings \
reference-Bdecoding \

View File

@ -922,15 +922,16 @@ bool handle_alert(libtorrent::session& ses, libtorrent::alert* a
if (session_stats_alert* s = alert_cast<session_stats_alert>(a))
{
ses_view.update_counters(s->values, s->timestamp);
ses_view.update_counters(s->values, sizeof(s->values)/sizeof(s->values[0])
, duration_cast<microseconds>(s->timestamp().time_since_epoch()).count());
return true;
}
#ifndef TORRENT_DISABLE_DHT
if (dht_stats_alert* p = alert_cast<dht_stats_alert>(a))
{
dht_active_requests.swap(p->active_requests);
dht_routing_table.swap(p->routing_table);
dht_active_requests = p->active_requests;
dht_routing_table = p->routing_table;
return true;
}
#endif
@ -1959,10 +1960,10 @@ int main(int argc, char* argv[])
}
// loop through the alert queue to see if anything has happened.
std::deque<alert*> alerts;
std::vector<alert*> alerts;
ses.pop_alerts(&alerts);
std::string now = timestamp();
for (std::deque<alert*>::iterator i = alerts.begin()
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
TORRENT_TRY
@ -1976,7 +1977,6 @@ int main(int argc, char* argv[])
if (events.size() >= 20) events.pop_front();
}
} TORRENT_CATCH(std::exception& e) {}
delete *i;
}
alerts.clear();
@ -2323,16 +2323,13 @@ int main(int argc, char* argv[])
alert const* a = ses.wait_for_alert(seconds(10));
if (a == 0) continue;
std::deque<alert*> alerts;
std::vector<alert*> alerts;
ses.pop_alerts(&alerts);
std::string now = timestamp();
for (std::deque<alert*>::iterator i = alerts.begin()
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
// make sure to delete each alert
std::auto_ptr<alert> a(*i);
torrent_paused_alert const* tp = alert_cast<torrent_paused_alert>(*i);
torrent_paused_alert* tp = alert_cast<torrent_paused_alert>(*i);
if (tp)
{
++num_paused;
@ -2350,7 +2347,7 @@ int main(int argc, char* argv[])
continue;
}
save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(*i);
save_resume_data_alert* rd = alert_cast<save_resume_data_alert>(*i);
if (!rd) continue;
--num_outstanding_resume_data;
printf("\rleft: %d failed: %d pause: %d "

View File

@ -182,8 +182,8 @@ void session_view::render()
}
}
void session_view::update_counters(std::vector<boost::uint64_t>& stats_counters
, boost::uint64_t t)
void session_view::update_counters(boost::uint64_t* stats_counters
, int num_cnt, boost::uint64_t t)
{
// only update the previous counters if there's been enough
// time since it was last updated
@ -193,7 +193,7 @@ void session_view::update_counters(std::vector<boost::uint64_t>& stats_counters
m_timestamp[1] = m_timestamp[0];
}
m_cnt[0].swap(stats_counters);
m_cnt[0].assign(stats_counters, stats_counters + num_cnt);
m_timestamp[0] = t;
render();
}

View File

@ -20,7 +20,7 @@ struct session_view
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
void update_counters(boost::uint64_t* stats_counters, int num_cnt
, boost::uint64_t t);
private:

View File

@ -86,8 +86,13 @@ int main(int argc, char* argv[])
s.apply_settings(p);
break;
}
std::auto_ptr<alert> holder = s.pop_alert();
print_alert(holder.get());
std::vector<alert*> alerts;
s.pop_alerts(&alerts);
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
print_alert(*i);
}
}
printf("\x1b[1m\n\n===================== done mapping. Now deleting mappings ========================\n\n\n\x1b[0m");
@ -96,8 +101,13 @@ int main(int argc, char* argv[])
{
alert const* a = s.wait_for_alert(seconds(5));
if (a == 0) break;
std::auto_ptr<alert> holder = s.pop_alert();
print_alert(holder.get());
std::vector<alert*> alerts;
s.pop_alerts(&alerts);
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
print_alert(*i);
}
}

View File

@ -6,7 +6,6 @@ nobase_include_HEADERS = \
alert.hpp \
alert_manager.hpp \
alert_observer.hpp \
alert_dispatcher.hpp \
alert_types.hpp \
alloca.hpp \
allocator.hpp \
@ -57,6 +56,7 @@ nobase_include_HEADERS = \
gzip.hpp \
hasher.hpp \
hex.hpp \
heterogeneous_queue.hpp \
http_connection.hpp \
http_parser.hpp \
http_seed_connection.hpp \
@ -119,6 +119,7 @@ nobase_include_HEADERS = \
socket_type_fwd.hpp \
socks5_stream.hpp \
ssl_stream.hpp \
stack_allocator.hpp \
stat.hpp \
stat_cache.hpp \
storage.hpp \
@ -153,6 +154,7 @@ nobase_include_HEADERS = \
tommath_class.h \
tommath_superclass.h \
\
aux_/alert_manager_variadic_emplace.hpp \
aux_/session_call.hpp \
aux_/session_impl.hpp \
aux_/session_settings.hpp \

View File

@ -52,21 +52,27 @@ POSSIBILITY OF SUCH DAMAGE.
//
// The pop_alerts() function on session is the main interface for retrieving
// alerts (warnings, messages and errors from libtorrent). If no alerts have
// been posted by libtorrent pop_alert() will return an empty list.
// been posted by libtorrent pop_alerts() will return an empty list.
//
// By default, only errors are reported. set_alert_mask() can be used to
// specify which kinds of events should be reported. The alert mask is
// comprised by bits from the category_t enum.
//
// Every alert belongs to one or more category. There is a small cost involved
// in posting alerts. Only alerts that belong to an enabled category are
// Every alert belongs to one or more category. There is a cost associated with
// posting alerts. Only alerts that belong to an enabled category are
// posted. Setting the alert bitmask to 0 will disable all alerts (except those
// that are non-discardable).
// that are non-discardable). Alerts that are responses to API calls such as
// save_resume_data() and post_session_stats() are non-discardable and will be
// posted even if their category is disabled.
//
// There are other alert base classes that some alerts derive from, all the
// alerts that are generated for a specific torrent are derived from
// torrent_alert, and tracker events derive from tracker_alert.
//
// Alerts returned by pop_alerts() are only valid until the next call to
// pop_alerts(). You may not copy an alert object to access it after the next
// call to pop_alerts(). Internal members of alerts also become invalid once
// pop_alerts() is called again.
#ifdef _MSC_VER
#pragma warning(pop)
@ -208,22 +214,25 @@ namespace libtorrent {
//
// .. code:: c++
//
// std::auto_ptr<alert> a = ses.pop_alert();
// switch (a->type())
// {
// case read_piece_alert::alert_type:
// {
// read_piece_alert* p = (read_piece_alert*)a.get();
// if (p->ec) {
// // read_piece failed
// std::vector<alert*> alerts;
// ses.pop_alerts(&alerts);
// for (alert* i : alerts) {
// switch (a->type()) {
//
// case read_piece_alert::alert_type:
// {
// read_piece_alert* p = (read_piece_alert*)a;
// if (p->ec) {
// // read_piece failed
// break;
// }
// // use p
// break;
// }
// // use p
// break;
// }
// case file_renamed_alert::alert_type:
// {
// // etc...
// case file_renamed_alert::alert_type:
// {
// // etc...
// }
// }
// }
virtual int type() const = 0;
@ -242,18 +251,19 @@ namespace libtorrent {
// returns a bitmask specifying which categories this alert belong to.
virtual int category() const = 0;
#ifndef TORRENT_NO_DEPRECATE
// determines whether or not an alert is allowed to be discarded
// when the alert queue is full. There are a few alerts which may not be discared,
// since they would break the user contract, such as save_resume_data_alert.
virtual bool discardable() const { return true; }
TORRENT_DEPRECATED_PREFIX
virtual bool discardable() const TORRENT_DEPRECATED { return true; }
#ifndef TORRENT_NO_DEPRECATE
TORRENT_DEPRECATED_PREFIX
severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif
// returns a pointer to a copy of the alert.
virtual std::auto_ptr<alert> clone() const = 0;
#endif
private:
time_point m_timestamp;

View File

@ -36,10 +36,19 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/thread.hpp"
#include "libtorrent/heterogeneous_queue.hpp"
#include "libtorrent/stack_allocator.hpp"
#ifndef TORRENT_NO_DEPRECATE
#include <boost/function/function1.hpp>
#endif
#include <boost/function/function0.hpp>
#include <boost/shared_ptr.hpp>
#include <list>
#include <utility> // for std::forward
// used for emplace_alert() variadic template emulation for c++98
#define TORRENT_ALERT_MANAGER_MAX_ARITY 7
namespace libtorrent {
@ -54,26 +63,66 @@ namespace libtorrent {
, boost::uint32_t alert_mask = alert::error_notification);
~alert_manager();
void post_alert(const alert& alert_);
void post_alert_ptr(alert* alert_);
#if __cplusplus >= 201103L
template <class T, typename... Args>
void emplace_alert(Args&&... args)
{
mutex::scoped_lock lock(m_mutex);
#ifndef TORRENT_NO_DEPRECATE
if (m_dispatch)
{
m_dispatch(std::auto_ptr<alert>(new T(m_allocations[m_generation]
, std::forward<Args>(args)...)));
return;
}
#endif
// don't add more than this number of alerts, unless it's a
// high priority alert, in which case we try harder to deliver it
// for high priority alerts, double the upper limit
if (m_alerts[m_generation].size() >= m_queue_size_limit
* (1 + T::priority))
return;
T alert(m_allocations[m_generation], std::forward<Args>(args)...);
m_alerts[m_generation].push_back(alert);
maybe_notify(lock);
}
#else
// emulate variadic templates for c++98
#include "libtorrent/aux_/alert_manager_variadic_emplace.hpp"
#endif
bool pending() const;
std::auto_ptr<alert> get(int& num_resume);
void get_all(std::deque<alert*>* alerts, int& num_resume);
void get_all(std::vector<alert*>& alerts, int& num_resume);
template <class T>
bool should_post() const
{
mutex::scoped_lock lock(m_mutex);
if (m_alerts.size() >= m_queue_size_limit) return false;
if (m_alerts[m_generation].size() >= m_queue_size_limit
* (1 + T::priority))
{
return false;
}
return (m_alert_mask & T::static_category) != 0;
}
bool should_post(alert const* a) const
{
return (m_alert_mask & a->category()) != 0;
mutex::scoped_lock lock(m_mutex);
boost::uint32_t mask = m_alert_mask;
lock.unlock();
return (mask & a->category()) != 0;
}
alert const* wait_for_alert(time_duration max_wait);
alert* wait_for_alert(time_duration max_wait);
void set_alert_mask(boost::uint32_t m)
{
@ -81,12 +130,20 @@ namespace libtorrent {
m_alert_mask = m;
}
int alert_mask() const { return m_alert_mask; }
boost::uint32_t alert_mask() const
{
mutex::scoped_lock lock(m_mutex);
return m_alert_mask;
}
size_t alert_queue_size_limit() const { return m_queue_size_limit; }
size_t set_alert_queue_size_limit(size_t queue_size_limit_);
void set_notify_function(boost::function<void()> const& fun);
#ifndef TORRENT_NO_DEPRECATE
void set_dispatch_function(boost::function<void(std::auto_ptr<alert>)> const&);
#endif
int num_queued_resume() const;
@ -95,24 +152,55 @@ namespace libtorrent {
#endif
private:
void post_impl(std::auto_ptr<alert>& alert_, mutex::scoped_lock& l);
std::deque<alert*> m_alerts;
// non-copyable
alert_manager(alert_manager const&);
alert_manager& operator=(alert_manager const&);
void maybe_notify(mutex::scoped_lock& lock);
mutable mutex m_mutex;
condition_variable m_condition;
boost::uint32_t m_alert_mask;
size_t m_queue_size_limit;
#ifndef TORRENT_NO_DEPRECATE
bool maybe_dispatch(alert const& a);
boost::function<void(std::auto_ptr<alert>)> m_dispatch;
#endif
// this function (if set) is called whenever the number of alerts in
// the alert queue goes from 0 to 1. The client is expected to wake up
// its main message loop for it to poll for alerts (using get_alerts()).
// That call will drain every alert in one atomic operation and this
// notification function will be called again the next time an alert is
// posted to the queue
boost::function<void()> m_notify;
// the number of resume data alerts in the alert queue
int m_num_queued_resume;
// this is either 0 or 1, it indicates which m_alerts and m_allocations
// the alert_manager is allowed to use right now. This is swapped when
// the client calls get_all(), at which point
int m_generation;
// this is where all alerts are queued up. There are two heterogenous
// queues to double buffer the thread access. The mutex in the alert
// manager gives exclusive access to m_alerts[m_generation] and
// m_allocations[m_generation] whereas the other copy is exclusively
// used by the client thread.
heterogeneous_queue<alert> m_alerts[2];
// this is a stack where alerts can allocate variable length content,
// such as strings, to go with the alerts.
aux::stack_allocator m_allocations[2];
#ifndef TORRENT_DISABLE_EXTENSIONS
typedef std::list<boost::shared_ptr<plugin> > ses_extension_list_t;
ses_extension_list_t m_ses_extensions;
#endif
};
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
#if !BOOST_PP_IS_ITERATING
// set-up iteration
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/iteration/iterate.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define BOOST_PP_ITERATION_PARAMS_1 \
(3, (0, TORRENT_ALERT_MANAGER_MAX_ARITY, \
"libtorrent/aux_/alert_manager_variadic_emplace.hpp"))
#include BOOST_PP_ITERATE()
#else // BOOST_PP_IS_ITERATING
// loop body
#define I BOOST_PP_ITERATION()
template <class T
BOOST_PP_COMMA_IF(I)
BOOST_PP_ENUM_PARAMS(I, typename A)>
void emplace_alert(BOOST_PP_ENUM_BINARY_PARAMS(I, A, const& a) )
{
mutex::scoped_lock lock(m_mutex);
#ifndef TORRENT_NO_DEPRECATE
if (m_dispatch)
{
m_dispatch(std::auto_ptr<alert>(new T(m_allocations[m_generation]
BOOST_PP_COMMA_IF(I)
BOOST_PP_ENUM_PARAMS(I, a))));
return;
}
#endif
// don't add more than this number of alerts, unless it's a
// high priority alert, in which case we try harder to deliver it
// for high priority alerts, double the upper limit
if (m_alerts[m_generation].size() >= m_queue_size_limit
* (1 + T::priority))
return;
T alert(m_allocations[m_generation]
BOOST_PP_COMMA_IF(I)
BOOST_PP_ENUM_PARAMS(I, a));
m_alerts[m_generation].push_back(alert);
maybe_notify(lock);
}
#undef I
#endif

View File

@ -93,7 +93,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/disk_io_job.hpp" // block_cache_reference
#include "libtorrent/network_thread_pool.hpp"
#include "libtorrent/peer_class_type_filter.hpp"
#include "libtorrent/alert_dispatcher.hpp"
#include "libtorrent/kademlia/dht_observer.hpp"
#include "libtorrent/resolver.hpp"
@ -170,7 +169,6 @@ namespace libtorrent
// thread started to run the main downloader loop
struct TORRENT_EXTRA_EXPORT session_impl
: session_interface
, alert_dispatcher
, dht::dht_observer
, boost::noncopyable
, initialize_timer
@ -425,14 +423,14 @@ namespace libtorrent
std::vector<torrent_handle> get_torrents() const;
size_t set_alert_queue_size_limit(size_t queue_size_limit_);
std::auto_ptr<alert> pop_alert();
void pop_alerts(std::deque<alert*>* alerts);
void set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const&);
alert const* wait_for_alert(time_duration max_wait);
void pop_alerts(std::vector<alert*>* alerts);
alert* wait_for_alert(time_duration max_wait);
#ifndef TORRENT_NO_DEPRECATE
void pop_alerts();
alert const* pop_alert();
void pop_alerts(std::deque<alert*>* alerts);
size_t set_alert_queue_size_limit(size_t queue_size_limit_);
int upload_rate_limit() const;
int download_rate_limit() const;
int local_upload_rate_limit() const;
@ -576,6 +574,10 @@ namespace libtorrent
// implements dht_observer
virtual void set_external_address(address const& ip
, address const& source);
virtual void get_peers(sha1_hash const& ih);
virtual void announce(sha1_hash const& ih, address const& addr, int port);
virtual void outgoing_get_peers(sha1_hash const& target
, sha1_hash const& sent_target, udp::endpoint const& ep);
void set_external_address(address const& ip
, int source_type, address const& source);
@ -619,9 +621,6 @@ namespace libtorrent
void submit_disk_jobs();
// implements alert_dispatcher
virtual bool post_alert(alert* a);
void update_proxy();
void update_i2p_bridge();
void update_peer_tos();
@ -702,6 +701,17 @@ namespace libtorrent
// handles delayed alerts
mutable alert_manager m_alerts;
#ifndef TORRENT_NO_DEPRECATE
// the alert pointers stored in m_alerts
mutable std::vector<alert*> m_alert_pointers;
// if not all the alerts in m_alert_pointers have been delivered to
// the client. This is the offset into m_alert_pointers where the next
// alert is. If this is greater than or equal to m_alert_pointers.size()
// it means we need to request new alerts from the main thread.
mutable int m_alert_pointer_pos;
#endif
// handles disk io requests asynchronously
// peers have pointers into the disk buffer
// pool, and must be destructed before this

View File

@ -64,7 +64,6 @@ namespace libtorrent
struct block_cache_reference;
struct counters;
namespace aux { struct session_settings; }
struct alert_dispatcher;
#if TORRENT_USE_ASSERTS
class file_storage;
#endif
@ -330,8 +329,7 @@ namespace libtorrent
struct TORRENT_EXTRA_EXPORT block_cache : disk_buffer_pool
{
block_cache(int block_size, io_service& ios
, boost::function<void()> const& trigger_trim
, alert_dispatcher* alert_disp);
, boost::function<void()> const& trigger_trim);
private:
@ -447,7 +445,7 @@ namespace libtorrent
#ifndef TORRENT_NO_DEPRECATE
void get_stats(cache_status* ret) const;
#endif
void set_settings(aux::session_settings const& sett);
void set_settings(aux::session_settings const& sett, error_code& ec);
enum reason_t { ref_hashing = 0, ref_reading = 1, ref_flushing = 2 };
bool inc_block_refcount(cached_piece_entry* pe, int block, int reason);

View File

@ -136,6 +136,18 @@ public:
b.m_begin = NULL;
b.m_size = b.m_capacity = 0;
}
buffer& operator=(buffer&& b)
{
if (&b == this) return *this;
std::free(m_begin);
m_begin = b.m_begin;
m_size = b.m_size;
m_capacity = b.m_capacity;
b.m_begin = NULL;
b.m_size = b.m_capacity = 0;
return *this;
}
#endif
buffer& operator=(buffer const& b)

View File

@ -56,14 +56,12 @@ namespace libtorrent
{
namespace aux { struct session_settings; }
class alert;
struct alert_dispatcher;
struct disk_observer;
struct TORRENT_EXTRA_EXPORT disk_buffer_pool : boost::noncopyable
{
disk_buffer_pool(int block_size, io_service& ios
, boost::function<void()> const& trigger_trim
, alert_dispatcher* alert_disp);
, boost::function<void()> const& trigger_trim);
~disk_buffer_pool();
#if TORRENT_USE_ASSERTS
@ -98,7 +96,7 @@ namespace libtorrent
boost::uint32_t num_to_evict(int num_needed = 0);
bool exceeded_max_size() const { return m_exceeded_max_size; }
void set_settings(aux::session_settings const& sett);
void set_settings(aux::session_settings const& sett, error_code& ec);
struct handler_t
{
@ -169,8 +167,6 @@ namespace libtorrent
std::vector<int> m_free_list;
#endif
alert_dispatcher* m_post_alert;
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
// if this is true, all buffers are allocated
// from m_pool. If this is false, all buffers

View File

@ -61,9 +61,9 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
class alert;
struct alert_dispatcher;
struct add_torrent_params;
struct counters;
class alert_manager;
struct cached_piece_info
{
@ -281,13 +281,12 @@ namespace libtorrent
, buffer_allocator_interface
{
disk_io_thread(io_service& ios
, alert_dispatcher* alert_disp
, counters& cnt
, void* userdata
, int block_size = 16 * 1024);
~disk_io_thread();
void set_settings(settings_pack* sett);
void set_settings(settings_pack* sett, alert_manager& alerts);
void set_num_threads(int i, bool wait = true);
void async_read(piece_manager* storage, peer_request const& r
@ -587,10 +586,6 @@ namespace libtorrent
// used to rate limit disk performance warnings
time_point m_last_disk_aio_performance_warning;
// function to be posted to the network thread to post
// an alert (used for performance warnings)
alert_dispatcher* m_post_alert;
// jobs that are completed are put on this queue
// whenever the queue size grows from 0 to 1
// a message is posted to the network thread, which

View File

@ -0,0 +1,219 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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
POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_HETEROGENEOUS_QUEUE_HPP_INCLUDED
#define TORRENT_HETEROGENEOUS_QUEUE_HPP_INCLUDED
#include <vector>
#include <boost/cstdint.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include "libtorrent/assert.hpp"
namespace libtorrent {
template <class T>
struct heterogeneous_queue
{
heterogeneous_queue()
: m_storage(NULL)
, m_capacity(0)
, m_size(0)
, m_num_items(0)
{}
// TODO: 2 add emplace_back() version
template <class U>
typename boost::enable_if<boost::is_base_of<T, U> >::type
push_back(U const& a)
{
// the size of the type rounded up to pointer alignment
const int object_size = (sizeof(U) + sizeof(*m_storage) - 1)
/ sizeof(*m_storage);
// +1 for the length prefix
if (m_size + object_size + header_size > m_capacity)
grow_capacity(object_size);
uintptr_t* ptr = m_storage + m_size;
// length prefix
header_t* hdr = (header_t*)ptr;
hdr->len = object_size;
hdr->move = &move<U>;
ptr += header_size;
// construct in-place
new (ptr) U(a);
// if we constructed the object without throwing any exception
// update counters to indicate the new item is in there
++m_num_items;
m_size += header_size + object_size;
}
void get_pointers(std::vector<T*>& out)
{
out.clear();
uintptr_t* ptr = m_storage;
uintptr_t const* const end = m_storage + m_size;
while (ptr < end)
{
header_t* hdr = (header_t*)ptr;
ptr += header_size;
TORRENT_ASSERT(ptr + hdr->len <= end);
out.push_back((T*)ptr);
ptr += hdr->len;
}
}
void swap(heterogeneous_queue& rhs)
{
std::swap(m_storage, rhs.m_storage);
std::swap(m_capacity, rhs.m_capacity);
std::swap(m_size, rhs.m_size);
std::swap(m_num_items, rhs.m_num_items);
}
int size() const { return m_num_items; }
bool empty() const { return m_num_items == 0; }
void clear()
{
uintptr_t* ptr = m_storage;
uintptr_t const* const end = m_storage + m_size;
while (ptr < end)
{
header_t* hdr = (header_t*)ptr;
ptr += header_size;
TORRENT_ASSERT(ptr + hdr->len <= end);
T* a = (T*)ptr;
a->~T();
ptr += hdr->len;
}
m_size = 0;
m_num_items = 0;
}
T* front()
{
if (m_size == 0) return NULL;
TORRENT_ASSERT(m_size > 1);
uintptr_t* ptr = m_storage;
header_t* hdr = (header_t*)ptr;
ptr += header_size;
TORRENT_ASSERT(hdr->len <= m_size);
return (T*)ptr;
}
~heterogeneous_queue()
{
clear();
delete[] m_storage;
}
private:
// non-copyable
heterogeneous_queue(heterogeneous_queue const&);
heterogeneous_queue& operator=(heterogeneous_queue const&);
// this header is put in front of every element. It tells us
// how many uintptr_t's it's using for its allocation, and it
// also tells us how to move this type if we need to grow our
// allocation.
struct header_t
{
int len;
void (*move)(uintptr_t* dst, uintptr_t* src);
};
const static int header_size = (sizeof(header_t) + sizeof(uintptr_t)
- 1) / sizeof(uintptr_t);
void grow_capacity(int size)
{
int amount_to_grow = (std::max)(size + header_size
, (std::max)(m_capacity * 3 / 2, 128));
uintptr_t* new_storage = new uintptr_t[m_capacity + amount_to_grow];
uintptr_t* src = m_storage;
uintptr_t* dst = new_storage;
uintptr_t const* const end = m_storage + m_size;
while (src < end)
{
header_t* src_hdr = (header_t*)src;
header_t* dst_hdr = (header_t*)dst;
*dst_hdr = *src_hdr;
src += header_size;
dst += header_size;
TORRENT_ASSERT(src + src_hdr->len <= end);
// TODO: if this throws, should we do anything?
src_hdr->move(dst, src);
src += src_hdr->len;
dst += src_hdr->len;
}
delete[] m_storage;
m_storage = new_storage;
m_capacity += amount_to_grow;
}
template <class U>
static void move(uintptr_t* dst, uintptr_t* src)
{
U* rhs = (U*)src;
#if __cplusplus >= 201103L
new (dst) U(std::move(*rhs));
#else
new (dst) U(*rhs);
#endif
rhs->~U();
}
uintptr_t* m_storage;
// number of uintptr_t's allocated under m_storage
int m_capacity;
// the number of uintptr_t's used under m_storage
int m_size;
// the number of objects allocated under m_storage
int m_num_items;
};
}
#endif

View File

@ -42,6 +42,10 @@ namespace libtorrent { namespace dht
{
virtual void set_external_address(address const& addr
, address const& source) = 0;
virtual void get_peers(sha1_hash const& ih) = 0;
virtual void outgoing_get_peers(sha1_hash const& target
, sha1_hash const& sent_target, udp::endpoint const& ep) = 0;
virtual void announce(sha1_hash const& ih, address const& addr, int port) = 0;
};
}}

View File

@ -198,7 +198,7 @@ typedef std::map<node_id, dht_immutable_item> dht_immutable_table_t;
typedef std::map<node_id, dht_mutable_item> dht_mutable_table_t;
public:
node_impl(alert_dispatcher* alert_disp, udp_socket_interface* sock
node_impl(udp_socket_interface* sock
, libtorrent::dht_settings const& settings, node_id nid, address const& external_address
, dht_observer* observer, counters& cnt);
@ -286,8 +286,7 @@ public:
libtorrent::dht_settings const& settings() const { return m_settings; }
counters& stats_counters() const { return m_counters; }
void post_alert(alert* a);
dht_observer* observer() const { return m_observer; }
protected:
void send_single_refresh(udp::endpoint const& ep, int bucket
@ -331,7 +330,6 @@ private:
// secret random numbers used to create write tokens
int m_secret[2];
alert_dispatcher* m_post_alert;
udp_socket_interface* m_sock;
counters& m_counters;
};

View File

@ -1097,62 +1097,68 @@ namespace libtorrent
int max_connections() const TORRENT_DEPRECATED;
TORRENT_DEPRECATED_PREFIX
int max_uploads() const TORRENT_DEPRECATED;
TORRENT_DEPRECATED_PREFIX
std::auto_ptr<alert> pop_alert() TORRENT_DEPRECATED;
TORRENT_DEPRECATED_PREFIX
void pop_alerts(std::deque<alert*>* alerts) TORRENT_DEPRECATED;
#endif
// ``pop_alert()`` is used to ask the session if any errors or events has
// occurred. With settings_pack::alert_mask you can filter which alerts
// to receive through ``pop_alert()``. For information about the alert
// categories, see alerts_.
// Alerts is the main mechanism for libtorrent to report errors and
// events. ``pop_alerts`` fills in the vector passed to it with pointers
// to new alerts. The session still owns these alerts and they will stay
// valid until the next time ``pop_alerts`` is called. You may not delete
// the alert objects.
//
// ``pop_alerts()`` pops all pending alerts in a single call. In high
// performance environments with a very high alert churn rate, this can
// save significant amount of time compared to popping alerts one at a
// time. Each call requires one round-trip to the network thread. If
// alerts are produced in a higher rate than they can be popped (when
// popped one at a time) it's easy to get stuck in an infinite loop,
// trying to drain the alert queue. Popping the entire queue at once
// avoids this problem.
//
// However, the ``pop_alerts`` function comes with significantly more
// responsibility. You pass in an *empty* ``std::dequeue<alert*>`` to it.
// If it's not empty, all elements in it will be deleted and then
// cleared. All currently pending alerts are returned by being swapped
// into the passed in container. The responsibility of deleting the
// alerts is transferred to the caller. This means you need to call
// delete for each item in the returned dequeue. It's probably a good
// idea to delete the alerts as you handle them, to save one extra pass
// over the dequeue.
//
// Alternatively, you can pass in the same container the next time you
// call ``pop_alerts``.
//
// ``wait_for_alert`` blocks until an alert is available, or for no more
// than ``max_wait`` time. If ``wait_for_alert`` returns because of the
// time-out, and no alerts are available, it returns 0. If at least one
// alert was generated, a pointer to that alert is returned. The alert is
// not popped, any subsequent calls to ``wait_for_alert`` will return the
// same pointer until the alert is popped by calling ``pop_alert``. This
// is useful for leaving any alert dispatching mechanism independent of
// this blocking call, the dispatcher can be called and it can pop the
// alert independently.
//
// .. note::
// Although these functions are all thread-safe, popping alerts from
// multiple separate threads may introduce race conditions in that
// the thread issuing an asynchronous operation may not be the one
// receiving the alert with the result.
// It is safe to call ``pop_alerts`` from multiple different threads, as
// long as the alerts themselves are not accessed once another thread
// calls ``pop_alerts``. Doing this requires manual synchronization
// between the popping threads.
//
// ``wait_for_alert`` will block the current thread for ``max_wait`` time
// duration, or until another alert is posted. If an alert is available
// at the time of the call, it returns immediately. The returned alert
// pointer is the head of the alert queue. ``wait_for_alert`` does not
// pop alerts from the queue, it merely peeks at it. The returned alert
// will stay valid until ``pop_alerts`` is called twice. The first time
// will pop it and the second will free it.
//
// If there is no alert in the queue and no alert arrives within the
// specified timeout, ``wait_for_alert`` returns NULL.
//
// In the python binding, ``wait_for_alert`` takes the number of
// milliseconds to wait as an integer.
//
// To control the max number of alerts that's queued by the session, see
// The alert queue in the session will not grow indefinitely. Make sure
// to pop periodically to not miss notifications. To control the max
// number of alerts that's queued by the session, see
// ``session_settings::alert_queue_size``.
//
// Some alerts are considered so important that they are posted even when
// the alert queue is full. Some alerts are considered mandatory and cannot
// be disabled by the ``alert_mask``. For instance,
// save_resume_data_alert and save_resume_data_failed_alert are always
// posted, regardelss of the alert mask.
std::auto_ptr<alert> pop_alert();
void pop_alerts(std::deque<alert*>* alerts);
alert const* wait_for_alert(time_duration max_wait);
//
// To control which alerts are posted, set the alert_mask
// (settings_pack::alert_mask).
//
// the ``set_alert_notify`` function lets the client set a function object
// to be invoked every time the alert queue goes from having 0 alerts to
// 1 alert. This function is called from within libtorrent, it may be the
// main thread, or it may be from within a user call. The intention of
// of the function is that the client wakes up its main thread, to poll
// for more alerts using ``pop_alerts()``. If the notify function fails
// to do so, it won't be called again, until ``pop_alerts`` is called for
// some other reason. For instance, it could signal an eventfd, post a
// message to an HWND or some other main message pump. The actual
// retrieval of alerts should not be done in the callback. In fact, the
// callback should not block. It should not perform any expensive work.
// It really should just notify the main application thread.
void pop_alerts(std::vector<alert*>* alerts);
alert* wait_for_alert(time_duration max_wait);
void set_alert_notify(boost::function<void()> const& fun);
#ifndef TORRENT_NO_DEPRECATE
TORRENT_DEPRECATED_PREFIX
@ -1173,20 +1179,19 @@ namespace libtorrent
void set_alert_mask(boost::uint32_t m) TORRENT_DEPRECATED;
TORRENT_DEPRECATED_PREFIX
boost::uint32_t get_alert_mask() const TORRENT_DEPRECATED;
#endif
// This sets a function to be called (from within libtorrent's netowrk
// thread) every time an alert is posted. Since the function (``fun``) is
// run in libtorrent's internal thread, it may not call any of
// libtorrent's external API functions. Doing so results in a dead lock.
// run in libtorrent's internal thread, it may not block.
//
// The main intention with this function is to support integration with
// platform-dependent message queues or signalling systems. For instance,
// on windows, one could post a message to an HNWD or on linux, write to
// a pipe or an eventfd.
void set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun);
TORRENT_DEPRECATED_PREFIX
void set_alert_dispatch(
boost::function<void(std::auto_ptr<alert>)> const& fun) TORRENT_DEPRECATED;
#ifndef TORRENT_NO_DEPRECATE
// Starts and stops Local Service Discovery. This service will broadcast
// the infohashes of all the non-private torrents on the local network to
// look for peers on the same swarm within multicast reach.

View File

@ -1,6 +1,6 @@
/*
Copyright (c) 2012-2014, Arvid Norberg
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -30,21 +30,76 @@ POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef TORRENT_ALERT_DISPATCHER_HPP_INCLUDED
#define TORRENT_ALERT_DISPATCHER_HPP_INCLUDED
#ifndef TORRENT_STACK_ALLOCATOR
namespace libtorrent
#include "libtorrent/assert.hpp"
#include "libtorrent/buffer.hpp"
namespace libtorrent { namespace aux
{
class alert;
struct TORRENT_EXPORT alert_dispatcher
struct stack_allocator
{
// return true if the alert was swallowed (i.e.
// ownership was taken over). In this case, the
// alert will not be passed on to any one else
virtual bool post_alert(alert* a) = 0;
stack_allocator() {}
int copy_string(std::string const& str)
{
int ret = int(m_storage.size());
m_storage.resize(ret + str.length() + 1);
strcpy(&m_storage[ret], str.c_str());
return ret;
}
int copy_string(char const* str)
{
int ret = int(m_storage.size());
int len = strlen(str);
m_storage.resize(ret + len + 1);
strcpy(&m_storage[ret], str);
return ret;
}
int allocate(int bytes)
{
int ret = int(m_storage.size());
m_storage.resize(ret + bytes);
return ret;
}
char* ptr(int idx)
{
TORRENT_ASSERT(idx >= 0);
TORRENT_ASSERT(idx < int(m_storage.size()));
return &m_storage[idx];
}
char const* ptr(int idx) const
{
TORRENT_ASSERT(idx >= 0);
TORRENT_ASSERT(idx < int(m_storage.size()));
return &m_storage[idx];
}
void swap(stack_allocator& rhs)
{
m_storage.swap(rhs.m_storage);
}
void reset()
{
m_storage.clear();
}
private:
// non-copyable
stack_allocator(stack_allocator const&);
stack_allocator& operator=(stack_allocator const&);
buffer m_storage;
};
}
} }
#endif

View File

@ -689,8 +689,7 @@ namespace libtorrent
// extern int outstanding_resume_data; // global counter of outstanding resume data
// std::vector<torrent_handle> handles = ses.get_torrents();
// ses.pause();
// for (std::vector<torrent_handle>::iterator i = handles.begin();
// i != handles.end(); ++i)
// for (torrent_handle i : handles)
// {
// torrent_handle& h = *i;
// if (!h.is_valid()) continue;
@ -709,30 +708,35 @@ namespace libtorrent
// // if we don't get an alert within 10 seconds, abort
// if (a == 0) break;
//
// std::auto_ptr<alert> holder = ses.pop_alert();
// std::vector<alert*> alerts;
// ses.pop_alerts(&alerts);
//
// if (alert_cast<save_resume_data_failed_alert>(a))
// {
// process_alert(a);
// --outstanding_resume_data;
// continue;
// }
// for (alert* i : alerts)
// {
// if (alert_cast<save_resume_data_failed_alert>(a))
// {
// process_alert(a);
// --outstanding_resume_data;
// continue;
// }
//
// save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a);
// if (rd == 0)
// {
// process_alert(a);
// continue;
// }
// save_resume_data_alert const* rd = alert_cast<save_resume_data_alert>(a);
// if (rd == 0)
// {
// process_alert(a);
// continue;
// }
//
// torrent_handle h = rd->handle;
// torrent_status st = h.status(torrent_handle::query_save_path | torrent_handle::query_name);
// std::ofstream out((st.save_path
// + "/" + st.name + ".fastresume").c_str()
// , std::ios_base::binary);
// out.unsetf(std::ios_base::skipws);
// bencode(std::ostream_iterator<char>(out), *rd->resume_data);
// --outstanding_resume_data;
// torrent_handle h = rd->handle;
// torrent_status st = h.status(torrent_handle::query_save_path
// | torrent_handle::query_name);
// std::ofstream out((st.save_path
// + "/" + st.name + ".fastresume").c_str()
// , std::ios_base::binary);
// out.unsetf(std::ios_base::skipws);
// bencode(std::ostream_iterator<char>(out), *rd->resume_data);
// --outstanding_resume_data;
// }
// }
//
//.. note::

View File

@ -42,6 +42,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/extensions.hpp"
#include "libtorrent/torrent.hpp"
#include "libtorrent/aux_/time.hpp"
#include "libtorrent/performance_counters.hpp"
#include "libtorrent/stack_allocator.hpp"
#include "libtorrent/aux_/escape_string.hpp" // for convert_from_native
@ -53,22 +55,41 @@ namespace libtorrent {
alert::~alert() {}
time_point alert::timestamp() const { return m_timestamp; }
torrent_alert::torrent_alert(torrent_handle const& h)
torrent_alert::torrent_alert(aux::stack_allocator& alloc
, torrent_handle const& h)
: handle(h)
, name(h.native_handle() ? h.native_handle()->name() : "")
, m_alloc(alloc)
{
if (name.empty() && h.is_valid())
std::string name_str;
if (h.native_handle())
{
m_name_idx = alloc.copy_string(h.native_handle()->name());
}
else if (h.is_valid())
{
char msg[41];
to_hex((char const*)&h.native_handle()->info_hash()[0], 20, msg);
name = msg;
m_name_idx = alloc.copy_string(msg);
}
else
{
m_name_idx = alloc.copy_string("");
}
#ifndef TORRENT_NO_DEPRECATE
name = torrent_name();
#endif
}
char const* torrent_alert::torrent_name() const
{
return m_alloc.ptr(m_name_idx);
}
std::string torrent_alert::message() const
{
if (!handle.is_valid()) return " - ";
return name;
return torrent_name();
}
std::string peer_alert::message() const
@ -78,9 +99,23 @@ namespace libtorrent {
+ ", " + identify_client(pid) + ")";
}
tracker_alert::tracker_alert(aux::stack_allocator& alloc, torrent_handle const& h
, std::string const& u)
: torrent_alert(alloc, h)
#ifndef TORRENT_NO_DEPRECATE
, url(u)
#endif
, m_url_idx(alloc.copy_string(u))
{}
char const* tracker_alert::tracker_url() const
{
return m_alloc.ptr(m_url_idx);
}
std::string tracker_alert::message() const
{
return torrent_alert::message() + " (" + url + ")";
return torrent_alert::message() + " (" + tracker_url() + ")";
}
std::string read_piece_alert::message() const
@ -107,11 +142,28 @@ namespace libtorrent {
return msg;
}
file_renamed_alert::file_renamed_alert(aux::stack_allocator& alloc
, torrent_handle const& h
, std::string const& n
, int idx)
: torrent_alert(alloc, h)
#ifndef TORRENT_NO_DEPRECATE
, name(n)
#endif
, index(idx)
, m_name_idx(alloc.copy_string(n))
{}
char const* file_renamed_alert::new_name() const
{
return m_alloc.ptr(m_name_idx);
}
std::string file_renamed_alert::message() const
{
char msg[200 + TORRENT_MAX_PATH * 2];
snprintf(msg, sizeof(msg), "%s: file %d renamed to %s", torrent_alert::message().c_str()
, index, name.c_str());
snprintf(msg, sizeof(msg), "%s: file %d renamed to %s"
, torrent_alert::message().c_str(), index, new_name());
return msg;
}
@ -155,18 +207,60 @@ namespace libtorrent {
+ state_str[state];
}
tracker_error_alert::tracker_error_alert(aux::stack_allocator& alloc
, torrent_handle const& h
, int times
, int status
, std::string const& u
, error_code const& e
, std::string const& m)
: tracker_alert(alloc, h, u)
, times_in_row(times)
, status_code(status)
, error(e)
#ifndef TORRENT_NO_DEPRECATE
, msg(m)
#endif
, m_msg_idx(alloc.copy_string(m))
{
TORRENT_ASSERT(!u.empty());
}
char const* tracker_error_alert::error_message() const
{
return m_alloc.ptr(m_msg_idx);
}
std::string tracker_error_alert::message() const
{
char ret[400];
snprintf(ret, sizeof(ret), "%s (%d) %s \"%s\" (%d)"
, tracker_alert::message().c_str(), status_code
, error.message().c_str(), msg.c_str(), times_in_row);
, error.message().c_str(), error_message(), times_in_row);
return ret;
}
tracker_warning_alert::tracker_warning_alert(aux::stack_allocator& alloc
, torrent_handle const& h
, std::string const& u
, std::string const& m)
: tracker_alert(alloc, h, u)
#ifndef TORRENT_NO_DEPRECATE
, msg(m)
#endif
, m_msg_idx(alloc.copy_string(m))
{
TORRENT_ASSERT(!u.empty());
}
char const* tracker_warning_alert::warning_message() const
{
return m_alloc.ptr(m_msg_idx);
}
std::string tracker_warning_alert::message() const
{
return tracker_alert::message() + " warning: " + msg;
return tracker_alert::message() + " warning: " + warning_message();
}
std::string scrape_reply_alert::message() const
@ -177,9 +271,43 @@ namespace libtorrent {
return ret;
}
scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc
, torrent_handle const& h
, std::string const& u
, error_code const& e)
: tracker_alert(alloc, h, u)
#ifndef TORRENT_NO_DEPRECATE
, msg(convert_from_native(e.message()))
#endif
, error(e)
, m_msg_idx(-1)
{
TORRENT_ASSERT(!u.empty());
}
scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc
, torrent_handle const& h
, std::string const& u
, std::string const& m)
: tracker_alert(alloc, h, u)
#ifndef TORRENT_NO_DEPRECATE
, msg(m)
#endif
, error(errors::tracker_failure)
, m_msg_idx(alloc.copy_string(m))
{
TORRENT_ASSERT(!u.empty());
}
char const* scrape_failed_alert::error_message() const
{
if (m_msg_idx == -1) return "";
else return m_alloc.ptr(m_msg_idx);
}
std::string scrape_failed_alert::message() const
{
return tracker_alert::message() + " scrape failed: " + msg;
return tracker_alert::message() + " scrape failed: " + error_message();
}
std::string tracker_reply_alert::message() const
@ -229,6 +357,12 @@ namespace libtorrent {
}
invalid_request_alert::invalid_request_alert(aux::stack_allocator& alloc
, torrent_handle const& h, tcp::endpoint const& ep
, peer_id const& peer_id, peer_request const& r)
: peer_alert(alloc, h, ep, peer_id)
, request(r)
{}
std::string invalid_request_alert::message() const
{
@ -238,6 +372,15 @@ namespace libtorrent {
return ret;
}
torrent_finished_alert::torrent_finished_alert(aux::stack_allocator& alloc,
torrent_handle h)
: torrent_alert(alloc, h)
{}
std::string torrent_finished_alert::message() const
{
return torrent_alert::message() + " torrent finished downloading";
}
std::string piece_finished_alert::message() const
{
@ -247,6 +390,15 @@ namespace libtorrent {
return ret;
}
request_dropped_alert::request_dropped_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int block_num
, int piece_num)
: peer_alert(alloc, h, ep, peer_id)
, block_index(block_num)
, piece_index(piece_num)
{
TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);
}
std::string request_dropped_alert::message() const
{
@ -256,6 +408,16 @@ namespace libtorrent {
return ret;
}
block_timeout_alert::block_timeout_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int block_num
, int piece_num)
: peer_alert(alloc, h, ep, peer_id)
, block_index(block_num)
, piece_index(piece_num)
{
TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);
}
std::string block_timeout_alert::message() const
{
char ret[200];
@ -264,6 +426,16 @@ namespace libtorrent {
return ret;
}
block_finished_alert::block_finished_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int block_num
, int piece_num)
: peer_alert(alloc, h, ep, peer_id)
, block_index(block_num)
, piece_index(piece_num)
{
TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);
}
std::string block_finished_alert::message() const
{
char ret[200];
@ -272,6 +444,19 @@ namespace libtorrent {
return ret;
}
block_downloading_alert::block_downloading_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep
, peer_id const& peer_id, int block_num, int piece_num)
: peer_alert(alloc, h, ep, peer_id)
#ifndef TORRENT_NO_DEPRECATE
, peer_speedmsg("")
#endif
, block_index(block_num)
, piece_index(piece_num)
{
TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);
}
std::string block_downloading_alert::message() const
{
char ret[200];
@ -280,6 +465,16 @@ namespace libtorrent {
return ret;
}
unwanted_block_alert::unwanted_block_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep
, peer_id const& peer_id, int block_num, int piece_num)
: peer_alert(alloc, h, ep, peer_id)
, block_index(block_num)
, piece_index(piece_num)
{
TORRENT_ASSERT(block_index >= 0 && piece_index >= 0);
}
std::string unwanted_block_alert::message() const
{
char ret[200];
@ -288,6 +483,139 @@ namespace libtorrent {
return ret;
}
storage_moved_alert::storage_moved_alert(aux::stack_allocator& alloc
, torrent_handle const& h, std::string const& p)
: torrent_alert(alloc, h)
#ifndef TORRENT_NO_DEPRECATE
, path(p)
#endif
, m_path_idx(alloc.copy_string(p))
{}
std::string storage_moved_alert::message() const
{
return torrent_alert::message() + " moved storage to: "
+ storage_path();
}
char const* storage_moved_alert::storage_path() const
{
return m_alloc.ptr(m_path_idx);
}
storage_moved_failed_alert::storage_moved_failed_alert(
aux::stack_allocator& alloc
, torrent_handle const& h
, error_code const& e
, std::string const& file
, char const* op)
: torrent_alert(alloc, h)
, error(e)
#ifndef TORRENT_NO_DEPRECATE
, file(file)
#endif
, operation(op)
, m_file_idx(alloc.copy_string(file))
{}
char const* storage_moved_failed_alert::file_path() const
{
return m_alloc.ptr(m_file_idx);
}
std::string storage_moved_failed_alert::message() const
{
return torrent_alert::message() + " storage move failed. "
+ (operation?operation:"") + " (" + file_path() + "): "
+ convert_from_native(error.message());
}
torrent_deleted_alert::torrent_deleted_alert(aux::stack_allocator& alloc
, torrent_handle const& h, sha1_hash const& ih)
: torrent_alert(alloc, h)
, info_hash(ih)
{}
std::string torrent_deleted_alert::message() const
{
return torrent_alert::message() + " deleted";
}
torrent_delete_failed_alert::torrent_delete_failed_alert(aux::stack_allocator& alloc
, torrent_handle const& h, error_code const& e, sha1_hash const& ih)
: torrent_alert(alloc, h)
, error(e)
, info_hash(ih)
{
#ifndef TORRENT_NO_DEPRECATE
msg = convert_from_native(error.message());
#endif
}
std::string torrent_delete_failed_alert::message() const
{
return torrent_alert::message() + " torrent deletion failed: "
+convert_from_native(error.message());
}
save_resume_data_alert::save_resume_data_alert(aux::stack_allocator& alloc
, boost::shared_ptr<entry> const& rd
, torrent_handle const& h)
: torrent_alert(alloc, h)
, resume_data(rd)
{}
std::string save_resume_data_alert::message() const
{
return torrent_alert::message() + " resume data generated";
}
save_resume_data_failed_alert::save_resume_data_failed_alert(aux::stack_allocator& alloc
, torrent_handle const& h, error_code const& e)
: torrent_alert(alloc, h)
, error(e)
{
#ifndef TORRENT_NO_DEPRECATE
msg = convert_from_native(error.message());
#endif
}
std::string save_resume_data_failed_alert::message() const
{
return torrent_alert::message() + " resume data was not generated: "
+ convert_from_native(error.message());
}
torrent_paused_alert::torrent_paused_alert(aux::stack_allocator& alloc
, torrent_handle const& h)
: torrent_alert(alloc, h)
{}
std::string torrent_paused_alert::message() const
{
return torrent_alert::message() + " paused";
}
torrent_resumed_alert::torrent_resumed_alert(aux::stack_allocator& alloc
, torrent_handle const& h)
: torrent_alert(alloc, h)
{}
std::string torrent_resumed_alert::message() const
{
return torrent_alert::message() + " resumed";
}
torrent_checked_alert::torrent_checked_alert(aux::stack_allocator& alloc
, torrent_handle const& h)
: torrent_alert(alloc, h)
{}
std::string torrent_checked_alert::message() const
{
return torrent_alert::message() + " checked";
}
namespace
{
static char const* const sock_type_str[] =
@ -311,6 +639,28 @@ namespace libtorrent {
};
}
listen_failed_alert::listen_failed_alert(
aux::stack_allocator& alloc
, std::string iface
, int op
, error_code const& ec
, socket_type_t t)
:
#ifndef TORRENT_NO_DEPRECATE
interface(iface),
#endif
error(ec)
, operation(op)
, sock_type(t)
, m_alloc(alloc)
, m_interface_idx(alloc.copy_string(iface))
{}
char const* listen_failed_alert::listen_interface() const
{
return m_alloc.ptr(m_interface_idx);
}
std::string listen_failed_alert::message() const
{
static char const* op_str[] =
@ -324,7 +674,7 @@ namespace libtorrent {
};
char ret[300];
snprintf(ret, sizeof(ret), "listening on %s failed: [%s] [%s] %s"
, interface.c_str()
, listen_interface()
, op_str[operation]
, sock_type_str[sock_type]
, convert_from_native(error.message()).c_str());
@ -353,13 +703,59 @@ namespace libtorrent {
return ret;
}
portmap_log_alert::portmap_log_alert(aux::stack_allocator& alloc, int t, const char* m)
: map_type(t)
#ifndef TORRENT_NO_DEPRECATE
, msg(m)
#endif
, m_alloc(alloc)
, m_log_idx(alloc.copy_string(m))
{}
char const* portmap_log_alert::log_message() const
{
return m_alloc.ptr(m_log_idx);
}
std::string portmap_log_alert::message() const
{
char ret[600];
snprintf(ret, sizeof(ret), "%s: %s", nat_type_str[map_type], msg.c_str());
snprintf(ret, sizeof(ret), "%s: %s", nat_type_str[map_type]
, log_message());
return ret;
}
fastresume_rejected_alert::fastresume_rejected_alert(
aux::stack_allocator& alloc
, torrent_handle const& h
, error_code const& ec
, std::string const& file
, char const* op)
: torrent_alert(alloc, h)
, error(ec)
#ifndef TORRENT_NO_DEPRECATE
, file(file)
#endif
, operation(op)
, m_path_idx(alloc.copy_string(file))
{
#ifndef TORRENT_NO_DEPRECATE
msg = convert_from_native(error.message());
#endif
}
std::string fastresume_rejected_alert::message() const
{
return torrent_alert::message() + " fast resume rejected. "
+ (operation?operation:"") + "(" + file_path() + "): "
+ convert_from_native(error.message());
}
char const* fastresume_rejected_alert::file_path() const
{
return m_alloc.ptr(m_path_idx);
}
std::string peer_blocked_alert::message() const
{
error_code ec;
@ -401,8 +797,9 @@ namespace libtorrent {
return msg;
}
stats_alert::stats_alert(torrent_handle const& h, int in, stat const& s)
: torrent_alert(h)
stats_alert::stats_alert(aux::stack_allocator& alloc
, torrent_handle const& h, int in, stat const& s)
: torrent_alert(alloc, h)
, interval(in)
{
transferred[upload_payload] = s[stat::upload_payload].counter();
@ -450,7 +847,9 @@ namespace libtorrent {
return msg;
}
cache_flushed_alert::cache_flushed_alert(torrent_handle const& h): torrent_alert(h) {}
cache_flushed_alert::cache_flushed_alert(aux::stack_allocator& alloc
, torrent_handle const& h)
: torrent_alert(alloc, h) {}
std::string anonymous_mode_alert::message() const
{
@ -472,9 +871,26 @@ namespace libtorrent {
return msg;
}
trackerid_alert::trackerid_alert(
aux::stack_allocator& alloc
, torrent_handle const& h
, std::string const& u
, const std::string& id)
: tracker_alert(alloc, h, u)
#ifndef TORRENT_NO_DEPRECATE
, trackerid(id)
#endif
, m_tracker_idx(alloc.copy_string(id))
{}
char const* trackerid_alert::tracker_id() const
{
return m_alloc.ptr(m_tracker_idx);
}
std::string trackerid_alert::message() const
{
return "trackerid received: " + trackerid;
return std::string("trackerid received: ") + tracker_id();
}
std::string dht_bootstrap_alert::message() const
@ -493,6 +909,18 @@ namespace libtorrent {
}
#endif
torrent_error_alert::torrent_error_alert(
aux::stack_allocator& alloc
, torrent_handle const& h
, error_code const& e, std::string const& f)
: torrent_alert(alloc, h)
, error(e)
#ifndef TORRENT_NO_DEPRECATE
, error_file(f)
#endif
, m_file_idx(alloc.copy_string(f))
{}
std::string torrent_error_alert::message() const
{
char msg[200];
@ -524,6 +952,12 @@ namespace libtorrent {
return msg;
}
peer_connect_alert::peer_connect_alert(aux::stack_allocator& alloc, torrent_handle h
, tcp::endpoint const& ep, peer_id const& peer_id, int type)
: peer_alert(alloc, h, ep, peer_id)
, socket_type(type)
{}
std::string peer_connect_alert::message() const
{
char msg[600];
@ -573,10 +1007,22 @@ namespace libtorrent {
std::string session_stats_alert::message() const
{
char msg[100];
snprintf(msg, sizeof(msg), "session stats (%d values)", int(values.size()));
snprintf(msg, sizeof(msg), "session stats (%d values)", int(sizeof(values)));
return msg;
}
peer_error_alert::peer_error_alert(aux::stack_allocator& alloc, torrent_handle const& h
, tcp::endpoint const& ep, peer_id const& peer_id, int op
, error_code const& e)
: peer_alert(alloc, h, ep, peer_id)
, operation(op)
, error(e)
{
#ifndef TORRENT_NO_DEPRECATE
msg = convert_from_native(error.message());
#endif
}
std::string peer_error_alert::message() const
{
char msg[200];
@ -636,6 +1082,21 @@ namespace libtorrent {
}
#endif
peer_disconnected_alert::peer_disconnected_alert(aux::stack_allocator& alloc
, torrent_handle const& h, tcp::endpoint const& ep
, peer_id const& peer_id, operation_t op, int type, error_code const& e
, close_reason_t r)
: peer_alert(alloc, h, ep, peer_id)
, socket_type(type)
, operation(op)
, error(e)
, reason(r)
{
#ifndef TORRENT_NO_DEPRECATE
msg = convert_from_native(error.message());
#endif
}
std::string peer_disconnected_alert::message() const
{
char msg[600];
@ -724,19 +1185,52 @@ namespace libtorrent {
return msg;
}
log_alert::log_alert(aux::stack_allocator& alloc, char const* log)
: m_alloc(alloc)
, m_str_idx(alloc.copy_string(log))
{}
char const* log_alert::msg() const
{
return m_alloc.ptr(m_str_idx);
}
std::string log_alert::message() const
{
return msg;
return msg();
}
torrent_log_alert::torrent_log_alert(aux::stack_allocator& alloc, torrent_handle h
, char const* log)
: torrent_alert(alloc, h)
, m_str_idx(alloc.copy_string(log))
{}
char const* torrent_log_alert::msg() const
{
return m_alloc.ptr(m_str_idx);
}
std::string torrent_log_alert::message() const
{
return torrent_alert::message() + ": " + msg;
return torrent_alert::message() + ": " + msg();
}
peer_log_alert::peer_log_alert(aux::stack_allocator& alloc, torrent_handle const& h
, tcp::endpoint const& i
, peer_id const& pi, char const* log)
: peer_alert(alloc, h, i, pi)
, m_str_idx(alloc.copy_string(log))
{}
char const* peer_log_alert::msg() const
{
return m_alloc.ptr(m_str_idx);
}
std::string peer_log_alert::message() const
{
return torrent_alert::message() + " [" + print_endpoint(ip) + "] " + msg;
return torrent_alert::message() + " [" + print_endpoint(ip) + "] " + msg();
}
std::string lsd_error_alert::message() const
@ -744,6 +1238,12 @@ namespace libtorrent {
return "Local Service Discovery error: " + error.message();
}
session_stats_alert::session_stats_alert(aux::stack_allocator&, counters const& cnt)
{
for (int i = 0; i < counters::num_counters; ++i)
values[i] = cnt[i];
}
std::string dht_stats_alert::message() const
{
char buf[2048];
@ -753,5 +1253,75 @@ namespace libtorrent {
return buf;
}
url_seed_alert::url_seed_alert(aux::stack_allocator& alloc, torrent_handle const& h
, std::string const& u, error_code const& e)
: torrent_alert(alloc, h)
#ifndef TORRENT_NO_DEPRECATE
, url(u)
, msg(convert_from_native(e.message()))
#endif
, error(e)
, m_url_idx(alloc.copy_string(u))
, m_msg_idx(-1)
{}
url_seed_alert::url_seed_alert(aux::stack_allocator& alloc, torrent_handle const& h
, std::string const& u, std::string const& m)
: torrent_alert(alloc, h)
#ifndef TORRENT_NO_DEPRECATE
, url(u)
, msg(m)
#endif
, m_url_idx(alloc.copy_string(u))
, m_msg_idx(alloc.copy_string(m))
{}
std::string url_seed_alert::message() const
{
return torrent_alert::message() + " url seed ("
+ server_url() + ") failed: " + convert_from_native(error.message());
}
char const* url_seed_alert::server_url() const
{
return m_alloc.ptr(m_url_idx);
}
char const* url_seed_alert::error_message() const
{
if (m_msg_idx == -1) return "";
return m_alloc.ptr(m_msg_idx);
}
file_error_alert::file_error_alert(aux::stack_allocator& alloc
, error_code const& ec
, std::string const& file
, char const* op
, torrent_handle const& h)
: torrent_alert(alloc, h)
#ifndef TORRENT_NO_DEPRECATE
, file(file)
#endif
, error(ec)
, operation(op)
, m_file_idx(alloc.copy_string(file))
{
#ifndef TORRENT_NO_DEPRECATE
msg = convert_from_native(error.message());
#endif
}
char const* file_error_alert::filename() const
{
return m_alloc.ptr(m_file_idx);
}
std::string file_error_alert::message() const
{
return torrent_alert::message() + " "
+ (operation?operation:"") + " (" + filename()
+ ") error: " + convert_from_native(error.message());
}
} // namespace libtorrent

View File

@ -45,20 +45,10 @@ namespace libtorrent
: m_alert_mask(alert_mask)
, m_queue_size_limit(queue_limit)
, m_num_queued_resume(0)
, m_generation(0)
{}
alert_manager::~alert_manager()
{
while (!m_alerts.empty())
{
TORRENT_ASSERT(alert_cast<save_resume_data_alert>(m_alerts.front()) == 0
&& "shutting down session with remaining resume data alerts in the alert queue. "
"You proabably wany to make sure you always wait for all resume data "
"alerts before shutting down");
delete m_alerts.front();
m_alerts.pop_front();
}
}
alert_manager::~alert_manager() {}
int alert_manager::num_queued_resume() const
{
@ -66,101 +56,83 @@ namespace libtorrent
return m_num_queued_resume;
}
alert const* alert_manager::wait_for_alert(time_duration max_wait)
alert* alert_manager::wait_for_alert(time_duration max_wait)
{
mutex::scoped_lock lock(m_mutex);
if (!m_alerts.empty()) return m_alerts.front();
if (!m_alerts[m_generation].empty())
return m_alerts[m_generation].front();
// this call can be interrupted prematurely by other signals
m_condition.wait_for(lock, max_wait);
if (!m_alerts.empty()) return m_alerts.front();
if (!m_alerts[m_generation].empty())
return m_alerts[m_generation].front();
return NULL;
}
void alert_manager::set_dispatch_function(boost::function<void(std::auto_ptr<alert>)> const& fun)
void alert_manager::maybe_notify(mutex::scoped_lock& lock)
{
if (m_alerts[m_generation].size() == 1)
{
lock.unlock();
// we just posted to an empty queue. If anyone is waiting for
// alerts, we need to notify them. Also (potentially) call the
// user supplied m_notify callback to let the client wake up its
// message loop to poll for alerts.
if (m_notify) m_notify();
// TODO: 2 keep a count of the number of threads waiting. Only if it's
// > 0 notify them
m_condition.notify_all();
}
}
#ifndef TORRENT_NO_DEPRECATE
bool alert_manager::maybe_dispatch(alert const& a)
{
if (m_dispatch)
{
m_dispatch(a.clone());
return true;
}
return false;
}
void alert_manager::set_dispatch_function(
boost::function<void(std::auto_ptr<alert>)> const& fun)
{
mutex::scoped_lock lock(m_mutex);
m_dispatch = fun;
std::deque<alert*> alerts;
m_alerts.swap(alerts);
heterogeneous_queue<alert> storage;
m_alerts[m_generation].swap(storage);
lock.unlock();
while (!alerts.empty())
std::vector<alert*> alerts;
storage.get_pointers(alerts);
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
TORRENT_TRY {
m_dispatch(std::auto_ptr<alert>(alerts.front()));
} TORRENT_CATCH(std::exception&) {}
alerts.pop_front();
m_dispatch((*i)->clone());
}
}
void dispatch_alert(boost::function<void(alert const&)> dispatcher
, alert* alert_)
{
std::auto_ptr<alert> holder(alert_);
dispatcher(*alert_);
}
void alert_manager::post_alert_ptr(alert* alert_)
{
std::auto_ptr<alert> a(alert_);
#ifndef TORRENT_DISABLE_EXTENSIONS
for (ses_extension_list_t::iterator i = m_ses_extensions.begin()
, end(m_ses_extensions.end()); i != end; ++i)
{
TORRENT_TRY {
(*i)->on_alert(alert_);
} TORRENT_CATCH(std::exception&) {}
}
#endif
mutex::scoped_lock lock(m_mutex);
post_impl(a, lock);
}
void alert_manager::post_alert(const alert& alert_)
void alert_manager::set_notify_function(boost::function<void()> const& fun)
{
std::auto_ptr<alert> a(alert_.clone());
#ifndef TORRENT_DISABLE_EXTENSIONS
for (ses_extension_list_t::iterator i = m_ses_extensions.begin()
, end(m_ses_extensions.end()); i != end; ++i)
{
TORRENT_TRY {
(*i)->on_alert(&alert_);
} TORRENT_CATCH(std::exception&) {}
}
#endif
mutex::scoped_lock lock(m_mutex);
post_impl(a, lock);
}
void alert_manager::post_impl(std::auto_ptr<alert>& alert_
, mutex::scoped_lock& /* l */)
{
if (alert_cast<save_resume_data_failed_alert>(alert_.get())
|| alert_cast<save_resume_data_alert>(alert_.get()))
++m_num_queued_resume;
if (m_dispatch)
m_notify = fun;
if (!m_alerts[m_generation].empty())
{
TORRENT_ASSERT(m_alerts.empty());
TORRENT_TRY {
m_dispatch(alert_);
} TORRENT_CATCH(std::exception&) {}
}
else if (m_alerts.size() < m_queue_size_limit || !alert_->discardable())
{
m_alerts.push_back(alert_.release());
if (m_alerts.size() == 1)
m_condition.notify_all();
// never call a callback with the lock held!
lock.unlock();
m_notify();
}
}
@ -171,46 +143,29 @@ namespace libtorrent
}
#endif
std::auto_ptr<alert> alert_manager::get(int& num_resume)
void alert_manager::get_all(std::vector<alert*>& alerts, int& num_resume)
{
mutex::scoped_lock lock(m_mutex);
if (m_alerts.empty())
return std::auto_ptr<alert>(0);
TORRENT_ASSERT(m_num_queued_resume <= m_alerts[m_generation].size());
TORRENT_ASSERT(m_num_queued_resume <= int(m_alerts.size()));
alerts.clear();
if (m_alerts[m_generation].empty()) return;
alert* result = m_alerts.front();
m_alerts.pop_front();
if (alert_cast<save_resume_data_failed_alert>(result)
|| alert_cast<save_resume_data_alert>(result))
{
--m_num_queued_resume;
num_resume = 1;
}
else
{
num_resume = 0;
}
return std::auto_ptr<alert>(result);
}
void alert_manager::get_all(std::deque<alert*>* alerts, int& num_resume)
{
mutex::scoped_lock lock(m_mutex);
TORRENT_ASSERT(m_num_queued_resume <= int(m_alerts.size()));
m_alerts[m_generation].get_pointers(alerts);
num_resume = m_num_queued_resume;
m_num_queued_resume = 0;
if (m_alerts.empty()) return;
m_alerts.swap(*alerts);
// swap buffers
m_generation = (m_generation + 1) & 1;
// clear the one we will start writing to now
m_alerts[m_generation].clear();
m_allocations[m_generation].reset();
}
bool alert_manager::pending() const
{
mutex::scoped_lock lock(m_mutex);
return !m_alerts.empty();
return !m_alerts[m_generation].empty();
}
size_t alert_manager::set_alert_queue_size_limit(size_t queue_size_limit_)

View File

@ -41,7 +41,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/disk_io_thread.hpp" // disk_operation_failed
#include "libtorrent/invariant_check.hpp"
#include "libtorrent/alloca.hpp"
#include "libtorrent/alert_dispatcher.hpp"
#include "libtorrent/performance_counters.hpp"
#include "libtorrent/aux_/time.hpp"
@ -266,9 +265,8 @@ cached_piece_entry::~cached_piece_entry()
}
block_cache::block_cache(int block_size, io_service& ios
, boost::function<void()> const& trigger_trim
, alert_dispatcher* alert_disp)
: disk_buffer_pool(block_size, ios, trigger_trim, alert_disp)
, boost::function<void()> const& trigger_trim)
: disk_buffer_pool(block_size, ios, trigger_trim)
, m_last_cache_op(cache_miss)
, m_ghost_size(8)
, m_read_cache_size(0)
@ -1458,7 +1456,7 @@ void block_cache::get_stats(cache_status* ret) const
}
#endif
void block_cache::set_settings(aux::session_settings const& sett)
void block_cache::set_settings(aux::session_settings const& sett, error_code& ec)
{
// the ghost size is the number of pieces to keep track of
// after they are evicted. Since cache_size is blocks, the
@ -1467,7 +1465,7 @@ void block_cache::set_settings(aux::session_settings const& sett)
m_ghost_size = (std::max)(8, sett.get_int(settings_pack::cache_size)
/ (std::max)(sett.get_int(settings_pack::read_cache_line_size), 4) / 2);
disk_buffer_pool::set_settings(sett);
disk_buffer_pool::set_settings(sett, ec);
}
#if TORRENT_USE_INVARIANT_CHECKS

View File

@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/torrent_info.hpp" // for merkle_*()
#include "libtorrent/performance_counters.hpp" // for counters
#include "libtorrent/alert_manager.hpp"
#include <boost/bind.hpp>
#include <boost/next_prior.hpp>
@ -251,7 +252,7 @@ namespace libtorrent
// dummy torrent object pointer
boost::shared_ptr<char> dummy;
counters cnt;
disk_io_thread disk_thread(ios, 0, cnt, 0);
disk_io_thread disk_thread(ios, cnt, 0);
storage_params params;
params.files = &t.files();
@ -269,7 +270,9 @@ namespace libtorrent
sett.set_int(settings_pack::cache_size, 0);
sett.set_int(settings_pack::hashing_threads, 2);
disk_thread.set_settings(&sett);
// TODO: this should probably be optional
alert_manager dummy2(0, 0);
disk_thread.set_settings(&sett, dummy2);
int piece_counter = 0;
int completed_piece = 0;

View File

@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/io_service.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/alert_dispatcher.hpp"
#include "libtorrent/disk_observer.hpp"
#include <algorithm>
@ -91,16 +90,8 @@ namespace libtorrent
}
}
// this is posted to the network thread and run from there
static void alert_callback(alert_dispatcher* disp, alert* a)
{
if (disp && disp->post_alert(a)) return;
delete a;
}
disk_buffer_pool::disk_buffer_pool(int block_size, io_service& ios
, boost::function<void()> const& trigger_trim
, alert_dispatcher* alert_disp)
, boost::function<void()> const& trigger_trim)
: m_block_size(block_size)
, m_in_use(0)
, m_max_use(64)
@ -114,7 +105,6 @@ namespace libtorrent
, m_cache_fd(-1)
, m_cache_pool(0)
#endif
, m_post_alert(alert_disp)
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
, m_using_pool_allocator(false)
, m_want_pool_allocator(false)
@ -492,7 +482,8 @@ namespace libtorrent
return ret;
}
void disk_buffer_pool::set_settings(aux::session_settings const& sett)
void disk_buffer_pool::set_settings(aux::session_settings const& sett
, error_code& ec)
{
mutex::scoped_lock l(m_pool_mutex);
@ -569,11 +560,7 @@ namespace libtorrent
m_cache_fd = open(sett.get_str(settings_pack::mmap_cache).c_str(), O_RDWR | O_CREAT | O_EXLOCK | O_TRUNC, 0700);
if (m_cache_fd < 0)
{
if (m_post_alert)
{
error_code ec(errno, boost::system::generic_category());
m_ios.post(boost::bind(alert_callback, m_post_alert, new mmap_cache_alert(ec)));
}
ec.assign(errno, boost::system::generic_category());
}
else
{
@ -585,11 +572,8 @@ namespace libtorrent
, MAP_SHARED | MAP_NOCACHE, m_cache_fd, 0);
if (intptr_t(m_cache_pool) == -1)
{
if (m_post_alert)
{
error_code ec(errno, boost::system::generic_category());
m_ios.post(boost::bind(alert_callback, m_post_alert, new mmap_cache_alert(ec)));
}
ec.assign(errno, boost::system::generic_category());
m_cache_pool = 0;
// attempt to make MacOS not flush this to disk, making close()
// block for a long time

View File

@ -48,9 +48,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/disk_buffer_pool.hpp"
#include "libtorrent/disk_io_job.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/alert_dispatcher.hpp"
#include "libtorrent/uncork_interface.hpp"
#include "libtorrent/performance_counters.hpp"
#include "libtorrent/alert_manager.hpp"
#include "libtorrent/debug.hpp"
@ -155,7 +155,6 @@ namespace libtorrent
// ------- disk_io_thread ------
disk_io_thread::disk_io_thread(io_service& ios
, alert_dispatcher* alert_disp
, counters& cnt
, void* userdata
, int block_size)
@ -165,12 +164,11 @@ namespace libtorrent
, m_last_cache_expiry(min_time())
, m_last_file_check(clock_type::now())
, m_file_pool(40)
, m_disk_cache(block_size, ios, boost::bind(&disk_io_thread::trigger_cache_trim, this), alert_disp)
, m_disk_cache(block_size, ios, boost::bind(&disk_io_thread::trigger_cache_trim, this))
, m_stats_counters(cnt)
, m_ios(ios)
, m_work(io_service::work(m_ios))
, m_last_disk_aio_performance_warning(min_time())
, m_post_alert(alert_disp)
, m_outstanding_reclaim_message(false)
#if TORRENT_USE_ASSERTS
, m_magic(0x1337)
@ -179,7 +177,9 @@ namespace libtorrent
#if defined TORRENT_ASIO_DEBUGGING
add_outstanding_async("disk_io_thread::work");
#endif
m_disk_cache.set_settings(m_settings);
error_code ec;
m_disk_cache.set_settings(m_settings, ec);
TORRENT_ASSERT(!ec);
#ifdef TORRENT_DISK_STATS
if (g_access_log == NULL) g_access_log = fopen("file_access.log", "a+");
@ -289,12 +289,17 @@ namespace libtorrent
m_blocks_to_reclaim.clear();
}
void disk_io_thread::set_settings(settings_pack* pack)
void disk_io_thread::set_settings(settings_pack* pack, alert_manager& alerts)
{
TORRENT_ASSERT(m_magic == 0x1337);
mutex::scoped_lock l(m_cache_mutex);
apply_pack(pack, m_settings);
m_disk_cache.set_settings(m_settings);
error_code ec;
m_disk_cache.set_settings(m_settings, ec);
if (ec && alerts.should_post<mmap_cache_alert>())
{
alerts.emplace_alert<mmap_cache_alert>(ec);
}
}
// flush all blocks that are below p->hash.offset, since we've

View File

@ -283,8 +283,8 @@ namespace libtorrent
+ (" " + m_parser.message());
if (t->alerts().should_post<url_seed_alert>())
{
t->alerts().post_alert(url_seed_alert(t->get_handle(), url()
, error_msg));
t->alerts().emplace_alert<url_seed_alert>(t->get_handle(), url()
, error_msg);
}
received_bytes(0, bytes_transferred);
disconnect(error_code(m_parser.status_code(), get_http_category()), op_bittorrent, 1);

View File

@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/kademlia/dht_tracker.hpp"
#include "libtorrent/kademlia/msg.hpp"
// TODO: it would be nice to not have a dependency on session here
#include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/socket_io.hpp"
@ -138,7 +139,7 @@ namespace libtorrent { namespace dht
, rate_limited_udp_socket& sock
, dht_settings const& settings, counters& cnt, entry const* state)
: m_counters(cnt)
, m_dht(&ses, this, settings, extract_node_id(state)
, m_dht(this, settings, extract_node_id(state)
, ses.external_address().external_address(address_v4()), &ses, cnt)
, m_sock(sock)
, m_last_new_key(aux::time_now() - minutes(int(key_refresh)))

View File

@ -32,9 +32,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include <libtorrent/kademlia/get_peers.hpp>
#include <libtorrent/kademlia/node.hpp>
#include <libtorrent/kademlia/dht_observer.hpp>
#include <libtorrent/socket_io.hpp>
#include <libtorrent/performance_counters.hpp>
#include <libtorrent/alert_types.hpp>
namespace libtorrent { namespace dht
{
@ -144,8 +144,10 @@ bool get_peers::invoke(observer_ptr o)
a["info_hash"] = m_target.to_string();
if (m_noseeds) a["noseed"] = 1;
m_node.post_alert(new dht_outgoing_get_peers_alert(m_target, m_target
, o->target_ep()));
if (m_node.observer())
{
m_node.observer()->outgoing_get_peers(m_target, m_target, o->target_ep());
}
m_node.stats_counters().inc_stats_counter(counters::dht_get_peers_out);
@ -244,8 +246,11 @@ bool obfuscated_get_peers::invoke(observer_ptr o)
obfuscated_target |= m_target & mask;
a["info_hash"] = obfuscated_target.to_string();
m_node.post_alert(new dht_outgoing_get_peers_alert(m_target
, obfuscated_target, o->target_ep()));
if (m_node.observer())
{
m_node.observer()->outgoing_get_peers(m_target, obfuscated_target
, o->target_ep());
}
return m_node.m_rpc.invoke(e, o->target_ep(), o);
}

View File

@ -37,11 +37,11 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/io.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/hasher.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/random.hpp"
#include "libtorrent/aux_/session_impl.hpp"
#include "libtorrent/alert_types.hpp" // for dht_lookup
#include "libtorrent/kademlia/node_id.hpp"
#include "libtorrent/kademlia/rpc_manager.hpp"
#include "libtorrent/kademlia/routing_table.hpp"
@ -92,8 +92,7 @@ void purge_peers(std::set<peer_entry>& peers)
void nop() {}
node_impl::node_impl(alert_dispatcher* alert_disp
, udp_socket_interface* sock
node_impl::node_impl(udp_socket_interface* sock
, dht_settings const& settings, node_id nid, address const& external_address
, dht_observer* observer
, struct counters& cnt)
@ -104,7 +103,6 @@ node_impl::node_impl(alert_dispatcher* alert_disp
, m_observer(observer)
, m_last_tracker_tick(aux::time_now())
, m_last_self_refresh(min_time())
, m_post_alert(alert_disp)
, m_sock(sock)
, m_counters(cnt)
{
@ -112,14 +110,6 @@ node_impl::node_impl(alert_dispatcher* alert_disp
m_secret[1] = random();
}
void node_impl::post_alert(alert* a)
{
if (!m_post_alert)
delete a;
else
m_post_alert->post_alert(a);
}
bool node_impl::verify_token(std::string const& token, char const* info_hash
, udp::endpoint const& addr)
{
@ -600,11 +590,8 @@ void node_impl::status(session_status& s)
void node_impl::lookup_peers(sha1_hash const& info_hash, entry& reply
, bool noseed, bool scrape) const
{
if (m_post_alert)
{
alert* a = new dht_get_peers_alert(info_hash);
if (!m_post_alert->post_alert(a)) delete a;
}
if (m_observer)
m_observer->get_peers(info_hash);
table_t::const_iterator i = m_map.lower_bound(info_hash);
if (i == m_map.end()) return;
@ -954,11 +941,8 @@ void node_impl::incoming_request(msg const& m, entry& e)
sha1_hash info_hash(msg_keys[0].string_ptr());
if (m_post_alert)
{
alert* a = new dht_announce_alert(m.addr.address(), port, info_hash);
if (!m_post_alert->post_alert(a)) delete a;
}
if (m_observer)
m_observer->announce(info_hash, m.addr.address(), port);
if (!verify_token(msg_keys[2].string_value(), msg_keys[0].string_ptr(), m.addr))
{

View File

@ -422,8 +422,8 @@ namespace libtorrent
if (t && t->alerts().should_post<peer_connect_alert>())
{
t->alerts().post_alert(peer_connect_alert(
t->get_handle(), remote(), pid(), m_socket->type()));
t->alerts().emplace_alert<peer_connect_alert>(
t->get_handle(), remote(), pid(), m_socket->type());
}
#if defined TORRENT_LOGGING
peer_log("*** LOCAL ENDPOINT[ e: %s ]", print_endpoint(m_socket->local_endpoint(ec)).c_str());
@ -525,8 +525,8 @@ namespace libtorrent
boost::shared_ptr<torrent> t = m_torrent.lock();
if (t) h = t->get_handle();
m_ses.alerts().post_alert(peer_log_alert(
h, m_remote, m_peer_id, buf));
m_ses.alerts().emplace_alert<peer_log_alert>(
h, m_remote, m_peer_id, buf);
}
#endif
@ -2193,8 +2193,8 @@ namespace libtorrent
if (t->alerts().should_post<invalid_request_alert>())
{
t->alerts().post_alert(invalid_request_alert(
t->get_handle(), m_remote, m_peer_id, r));
t->alerts().emplace_alert<invalid_request_alert>(
t->get_handle(), m_remote, m_peer_id, r);
}
return;
}
@ -2284,8 +2284,8 @@ namespace libtorrent
if (t->alerts().should_post<invalid_request_alert>())
{
t->alerts().post_alert(invalid_request_alert(
t->get_handle(), m_remote, m_peer_id, r));
t->alerts().emplace_alert<invalid_request_alert>(
t->get_handle(), m_remote, m_peer_id, r);
}
// every ten invalid request, remind the peer that it's choked
@ -2463,8 +2463,8 @@ namespace libtorrent
{
if (t->alerts().should_post<unwanted_block_alert>())
{
t->alerts().post_alert(unwanted_block_alert(t->get_handle(), m_remote
, m_peer_id, b.block_index, b.piece_index));
t->alerts().emplace_alert<unwanted_block_alert>(t->get_handle()
, m_remote, m_peer_id, int(b.block_index), int(b.piece_index));
}
#if defined TORRENT_LOGGING
peer_log("*** The block we just got was not in the request queue ***");
@ -2603,8 +2603,8 @@ namespace libtorrent
{
if (t->alerts().should_post<peer_error_alert>())
{
t->alerts().post_alert(peer_error_alert(t->get_handle(), m_remote
, m_peer_id, op_bittorrent, errors::peer_sent_empty_piece));
t->alerts().emplace_alert<peer_error_alert>(t->get_handle(), m_remote
, m_peer_id, op_bittorrent, errors::peer_sent_empty_piece);
}
// This is used as a reject-request by bitcomet
incoming_reject_request(p);
@ -2648,8 +2648,9 @@ namespace libtorrent
{
if (t->alerts().should_post<unwanted_block_alert>())
{
t->alerts().post_alert(unwanted_block_alert(t->get_handle(), m_remote
, m_peer_id, block_finished.block_index, block_finished.piece_index));
t->alerts().emplace_alert<unwanted_block_alert>(t->get_handle()
, m_remote, m_peer_id, int(block_finished.block_index)
, int(block_finished.piece_index));
}
#if defined TORRENT_LOGGING
peer_log("*** The block we just got was not in the request queue ***");
@ -2720,8 +2721,8 @@ namespace libtorrent
m_snubbed = false;
if (t->alerts().should_post<peer_unsnubbed_alert>())
{
t->alerts().post_alert(peer_unsnubbed_alert(t->get_handle()
, m_remote, m_peer_id));
t->alerts().emplace_alert<peer_unsnubbed_alert>(t->get_handle()
, m_remote, m_peer_id);
}
}
@ -2759,8 +2760,8 @@ namespace libtorrent
&& m_settings.get_int(settings_pack::cache_size) > 5
&& t->alerts().should_post<performance_alert>())
{
t->alerts().post_alert(performance_alert(t->get_handle()
, performance_alert::too_high_disk_queue_limit));
t->alerts().emplace_alert<performance_alert>(t->get_handle()
, performance_alert::too_high_disk_queue_limit);
}
m_request_time.add_sample(total_milliseconds(now - m_requested));
@ -2923,8 +2924,9 @@ namespace libtorrent
if (t->alerts().should_post<block_finished_alert>())
{
t->alerts().post_alert(block_finished_alert(t->get_handle(),
remote(), pid(), block_finished.block_index, block_finished.piece_index));
t->alerts().emplace_alert<block_finished_alert>(t->get_handle(),
remote(), pid(), int(block_finished.block_index)
, int(block_finished.piece_index));
}
disconnect_if_redundant();
@ -3358,8 +3360,8 @@ namespace libtorrent
if (t->alerts().should_post<block_downloading_alert>())
{
t->alerts().post_alert(block_downloading_alert(t->get_handle(),
remote(), pid(), block.block_index, block.piece_index));
t->alerts().emplace_alert<block_downloading_alert>(t->get_handle(),
remote(), pid(), block.block_index, block.piece_index);
}
pending_block pb(block);
@ -4079,8 +4081,8 @@ namespace libtorrent
&& t)
{
if (t->alerts().should_post<performance_alert>())
t->alerts().post_alert(performance_alert(
handle, performance_alert::too_few_outgoing_ports));
t->alerts().emplace_alert<performance_alert>(
handle, performance_alert::too_few_outgoing_ports);
}
if (t)
@ -4090,15 +4092,14 @@ namespace libtorrent
if ((error > 1 || ec.category() == get_socks_category())
&& t->alerts().should_post<peer_error_alert>())
{
t->alerts().post_alert(
peer_error_alert(handle, remote(), pid(), op, ec));
t->alerts().emplace_alert<peer_error_alert>(handle, remote()
, pid(), op, ec);
}
if (error <= 1 && t->alerts().should_post<peer_disconnected_alert>())
{
t->alerts().post_alert(
peer_disconnected_alert(handle, remote(), pid(), op
, m_socket->type(), ec, close_reason));
t->alerts().emplace_alert<peer_disconnected_alert>(handle
, remote(), pid(), op, m_socket->type(), ec, close_reason);
}
}
@ -4509,10 +4510,10 @@ namespace libtorrent
for (int channel = 0; channel < 2; ++channel)
{
if ((warning & (1 << channel)) == 0) continue;
t->alerts().post_alert(performance_alert(t->get_handle()
t->alerts().emplace_alert<performance_alert>(t->get_handle()
, channel == peer_connection::download_channel
? performance_alert::download_limit_too_low
: performance_alert::upload_limit_too_low));
: performance_alert::upload_limit_too_low);
}
}
@ -4713,8 +4714,8 @@ namespace libtorrent
if (m_desired_queue_size == m_max_out_request_queue
&& t->alerts().should_post<performance_alert>())
{
t->alerts().post_alert(performance_alert(t->get_handle()
, performance_alert::outstanding_request_limit_reached));
t->alerts().emplace_alert<performance_alert>(t->get_handle()
, performance_alert::outstanding_request_limit_reached);
}
int piece_timeout = m_settings.get_int(settings_pack::piece_timeout);
@ -4768,8 +4769,8 @@ namespace libtorrent
m_snubbed = true;
if (t->alerts().should_post<peer_snubbed_alert>())
{
t->alerts().post_alert(peer_snubbed_alert(t->get_handle()
, m_remote, m_peer_id));
t->alerts().emplace_alert<peer_snubbed_alert>(t->get_handle()
, m_remote, m_peer_id);
}
}
m_desired_queue_size = 1;
@ -4824,8 +4825,9 @@ namespace libtorrent
if (t->alerts().should_post<block_timeout_alert>())
{
t->alerts().post_alert(block_timeout_alert(t->get_handle()
, remote(), pid(), qe.block.block_index, qe.block.piece_index));
t->alerts().emplace_alert<block_timeout_alert>(t->get_handle()
, remote(), pid(), int(qe.block.block_index)
, int(qe.block.piece_index));
}
// request a new block before removing the previous
@ -5089,9 +5091,9 @@ namespace libtorrent
write_dont_have(r.piece);
write_reject_request(r);
if (t->alerts().should_post<file_error_alert>())
t->alerts().post_alert(file_error_alert(j->error.ec
t->alerts().emplace_alert<file_error_alert>(j->error.ec
, t->resolve_filename(j->error.file)
, j->error.operation_str(), t->get_handle()));
, j->error.operation_str(), t->get_handle());
++m_disk_read_failures;
if (m_disk_read_failures > 100) disconnect(j->error.ec, op_file_read);
@ -5343,8 +5345,8 @@ namespace libtorrent
// peer to hang on to the disk
if (t && t->alerts().should_post<performance_alert>())
{
t->alerts().post_alert(performance_alert(t->get_handle()
, performance_alert::send_buffer_watermark_too_low));
t->alerts().emplace_alert<performance_alert>(t->get_handle()
, performance_alert::send_buffer_watermark_too_low);
}
}
}

View File

@ -344,8 +344,8 @@ void feed::on_feed(error_code const& ec
m_error = ec;
if (m_ses.m_alerts.should_post<rss_alert>())
{
m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
, rss_alert::state_error, m_error));
m_ses.m_alerts.emplace_alert<rss_alert>(my_handle(), m_settings.url
, rss_alert::state_error, m_error);
}
return;
}
@ -356,8 +356,8 @@ void feed::on_feed(error_code const& ec
m_error = error_code(parser.status_code(), get_http_category());
if (m_ses.m_alerts.should_post<rss_alert>())
{
m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
, rss_alert::state_error, m_error));
m_ses.m_alerts.emplace_alert<rss_alert>(my_handle(), m_settings.url
, rss_alert::state_error, m_error);
}
return;
}
@ -391,8 +391,8 @@ void feed::on_feed(error_code const& ec
// report that we successfully updated the feed
if (m_ses.m_alerts.should_post<rss_alert>())
{
m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
, rss_alert::state_updated, error_code()));
m_ses.m_alerts.emplace_alert<rss_alert>(my_handle(), m_settings.url
, rss_alert::state_updated, error_code());
}
// update m_ses.m_next_rss_update timestamps
@ -541,7 +541,7 @@ void feed::add_item(feed_item const& item)
i.handle = torrent_handle(m_ses.find_torrent(i.uuid.empty() ? i.url : i.uuid));
if (m_ses.m_alerts.should_post<rss_item_alert>())
m_ses.m_alerts.post_alert(rss_item_alert(my_handle(), i));
m_ses.m_alerts.emplace_alert<rss_item_alert>(my_handle(), i);
if (m_settings.auto_download)
{
@ -581,8 +581,8 @@ int feed::update_feed()
if (m_ses.m_alerts.should_post<rss_alert>())
{
m_ses.m_alerts.post_alert(rss_alert(my_handle(), m_settings.url
, rss_alert::state_updating, error_code()));
m_ses.m_alerts.emplace_alert<rss_alert>(my_handle(), m_settings.url
, rss_alert::state_updating, error_code());
}
boost::shared_ptr<http_connection> feed(

View File

@ -1134,33 +1134,42 @@ namespace libtorrent
{
return TORRENT_SYNC_CALL_RET(int, num_connections);
}
#endif // TORRENT_NO_DEPRECATE
void session::set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun)
{
TORRENT_ASYNC_CALL1(set_alert_dispatch, fun);
m_impl->m_alerts.set_dispatch_function(fun);
}
#endif // TORRENT_NO_DEPRECATE
std::auto_ptr<alert> session::pop_alert()
{
return m_impl->pop_alert();
}
void session::pop_alerts(std::deque<alert*>* alerts)
{
for (std::deque<alert*>::iterator i = alerts->begin()
, end(alerts->end()); i != end; ++i)
delete *i;
alerts->clear();
m_impl->pop_alerts(alerts);
}
alert const* session::wait_for_alert(time_duration max_wait)
alert* session::wait_for_alert(time_duration max_wait)
{
return m_impl->wait_for_alert(max_wait);
}
// the alerts are const, they may not be deleted by the client
void session::pop_alerts(std::vector<alert*>* alerts)
{
m_impl->pop_alerts(alerts);
}
void session::set_alert_notify(boost::function<void()> const& fun)
{
m_impl->m_alerts.set_notify_function(fun);
}
#ifndef TORRENT_NO_DEPRECATE
void session::pop_alerts(std::deque<alert*>* alerts)
{
m_impl->pop_alerts(alerts);
}
std::auto_ptr<alert> session::pop_alert()
{
alert const* a = m_impl->pop_alert();
if (a == NULL) return std::auto_ptr<alert>();
return a->clone();
}
void session::set_alert_mask(boost::uint32_t m)
{
settings_pack p;

View File

@ -348,7 +348,10 @@ namespace aux {
, m_ssl_ctx(m_io_service, asio::ssl::context::sslv23)
#endif
, m_alerts(m_settings.get_int(settings_pack::alert_queue_size), alert::all_categories)
, m_disk_thread(m_io_service, this, m_stats_counters
#ifndef TORRENT_NO_DEPRECATE
, m_alert_pointer_pos(0)
#endif
, m_disk_thread(m_io_service, m_stats_counters
, (uncork_interface*)this)
, m_download_rate(peer_connection::download_channel)
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
@ -516,9 +519,9 @@ namespace aux {
#if defined TORRENT_LOGGING
session_log("libtorrent configuration: %s\n"
"libtorrent version: %s\n"
"libtorrent revision: %s\n\n"
session_log("config: %s\n"
"version: %s\n"
"revision: %s\n\n"
, TORRENT_CFG_STRING
, LIBTORRENT_VERSION
, LIBTORRENT_REVISION);
@ -1520,7 +1523,7 @@ namespace aux {
!= m_settings.get_str(settings_pack::listen_interfaces));
apply_pack(pack, m_settings, this);
m_disk_thread.set_settings(pack);
m_disk_thread.set_settings(pack, m_alerts);
delete pack;
if (reopen_listen_port)
@ -1574,7 +1577,7 @@ namespace aux {
if (ec)
{
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(device, last_op, ec, sock_type));
m_alerts.emplace_alert<listen_failed_alert>(device, last_op, ec, sock_type);
#if defined TORRENT_LOGGING
session_log("failed to open socket: %s: %s"
@ -1645,7 +1648,7 @@ namespace aux {
{
// not even that worked, give up
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(device, last_op, ec, sock_type));
m_alerts.emplace_alert<listen_failed_alert>(device, last_op, ec, sock_type);
#if defined TORRENT_LOGGING
session_log("cannot bind to interface \"%s\": %s"
, device.c_str(), ec.message().c_str());
@ -1663,7 +1666,7 @@ namespace aux {
if (ec)
{
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(device, last_op, ec, sock_type));
m_alerts.emplace_alert<listen_failed_alert>(device, last_op, ec, sock_type);
#if defined TORRENT_LOGGING
session_log("cannot listen on interface \"%s\": %s"
, device.c_str(), ec.message().c_str());
@ -1680,7 +1683,7 @@ namespace aux {
if (ec)
{
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(device, last_op, ec, sock_type));
m_alerts.emplace_alert<listen_failed_alert>(device, last_op, ec, sock_type);
#if defined TORRENT_LOGGING
session_log("failed to get peer name \"%s\": %s"
, device.c_str(), ec.message().c_str());
@ -1690,9 +1693,9 @@ namespace aux {
}
if (m_alerts.should_post<listen_succeeded_alert>())
m_alerts.post_alert(listen_succeeded_alert(tcp::endpoint(bind_ip, port)
m_alerts.emplace_alert<listen_succeeded_alert>(tcp::endpoint(bind_ip, port)
, (flags & open_ssl_socket) ? listen_succeeded_alert::tcp_ssl
: listen_succeeded_alert::tcp));
: listen_succeeded_alert::tcp);
#if defined TORRENT_LOGGING
session_log(" listening on: %s external port: %d"
@ -1886,10 +1889,10 @@ retry:
{
// only report this if both IPv4 and IPv6 fails for a device
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(device
m_alerts.emplace_alert<listen_failed_alert>(device
, listen_failed_alert::bind
, error_code(boost::system::errc::no_such_device, generic_category())
, listen_failed_alert::tcp));
, listen_failed_alert::tcp);
}
}
}
@ -1907,8 +1910,8 @@ retry:
goto retry;
}
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(print_endpoint(m_listen_interface)
, listen_failed_alert::bind, ec, listen_failed_alert::udp));
m_alerts.emplace_alert<listen_failed_alert>(print_endpoint(m_listen_interface)
, listen_failed_alert::bind, ec, listen_failed_alert::udp);
return;
}
@ -1931,17 +1934,17 @@ retry:
if (m_alerts.should_post<listen_failed_alert>())
{
error_code err;
m_alerts.post_alert(listen_failed_alert(print_endpoint(ssl_bind_if)
, listen_failed_alert::bind, ec, listen_failed_alert::utp_ssl));
m_alerts.emplace_alert<listen_failed_alert>(print_endpoint(ssl_bind_if)
, listen_failed_alert::bind, ec, listen_failed_alert::utp_ssl);
}
ec.clear();
}
else
{
if (m_alerts.should_post<listen_succeeded_alert>())
m_alerts.post_alert(listen_succeeded_alert(
m_alerts.emplace_alert<listen_succeeded_alert>(
tcp::endpoint(ssl_bind_if.address(), ssl_bind_if.port())
, listen_succeeded_alert::utp_ssl));
, listen_succeeded_alert::utp_ssl);
}
}
#endif // TORRENT_USE_OPENSSL
@ -1963,8 +1966,8 @@ retry:
if (m_alerts.should_post<listen_failed_alert>())
{
error_code err;
m_alerts.post_alert(listen_failed_alert(print_endpoint(m_listen_interface)
, listen_failed_alert::bind, ec, listen_failed_alert::udp));
m_alerts.emplace_alert<listen_failed_alert>(print_endpoint(m_listen_interface)
, listen_failed_alert::bind, ec, listen_failed_alert::udp);
}
return;
}
@ -1974,7 +1977,7 @@ retry:
maybe_update_udp_mapping(0, m_listen_interface.port(), m_listen_interface.port());
maybe_update_udp_mapping(1, m_listen_interface.port(), m_listen_interface.port());
if (m_alerts.should_post<listen_succeeded_alert>())
m_alerts.post_alert(listen_succeeded_alert(m_listen_interface, listen_succeeded_alert::udp));
m_alerts.emplace_alert<listen_succeeded_alert>(m_listen_interface, listen_succeeded_alert::udp);
}
if (m_settings.get_int(settings_pack::peer_tos) != 0)
@ -1988,7 +1991,7 @@ retry:
if (ec)
{
if (m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec));
m_alerts.emplace_alert<udp_error_alert>(udp::endpoint(), ec);
}
// initiate accepting on the listen sockets
@ -2095,7 +2098,7 @@ retry:
if (ec)
{
if (m_alerts.should_post<i2p_alert>())
m_alerts.post_alert(i2p_alert(ec));
m_alerts.emplace_alert<i2p_alert>(ec);
#if defined TORRENT_LOGGING
session_log("i2p open failed (%d) %s", ec.value(), ec.message().c_str());
@ -2140,8 +2143,8 @@ retry:
if (e)
{
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert("i2p", listen_failed_alert::accept
, e, listen_failed_alert::i2p));
m_alerts.emplace_alert<listen_failed_alert>("i2p", listen_failed_alert::accept
, e, listen_failed_alert::i2p);
#if defined TORRENT_LOGGING
session_log("cannot bind to port %d: %s"
, m_listen_interface.port(), e.message().c_str());
@ -2163,7 +2166,7 @@ retry:
// don't bubble up operation aborted errors to the user
if (ec != asio::error::operation_aborted
&& m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(ep, ec));
m_alerts.emplace_alert<udp_error_alert>(ep, ec);
#if defined TORRENT_LOGGING
session_log("UDP socket error: (%d) %s", ec.value(), ec.message().c_str());
@ -2263,8 +2266,8 @@ retry:
, boost::bind(&torrent_map::value_type::second, _1)));
if (m_alerts.should_post<performance_alert>())
m_alerts.post_alert(performance_alert(
torrent_handle(), performance_alert::too_few_file_descriptors));
m_alerts.emplace_alert<performance_alert>(
torrent_handle(), performance_alert::too_few_file_descriptors);
if (i != m_torrents.end())
{
@ -2279,8 +2282,8 @@ retry:
if (m_alerts.should_post<listen_failed_alert>())
{
error_code err;
m_alerts.post_alert(listen_failed_alert(print_endpoint(ep), listen_failed_alert::accept, e
, ssl ? listen_failed_alert::tcp_ssl : listen_failed_alert::tcp));
m_alerts.emplace_alert<listen_failed_alert>(print_endpoint(ep), listen_failed_alert::accept, e
, ssl ? listen_failed_alert::tcp_ssl : listen_failed_alert::tcp);
}
return;
}
@ -2351,8 +2354,8 @@ retry:
{
if (m_alerts.should_post<peer_error_alert>())
{
m_alerts.post_alert(peer_error_alert(torrent_handle(), endp
, peer_id(), op_ssl_handshake, ec));
m_alerts.emplace_alert<peer_error_alert>(torrent_handle(), endp
, peer_id(), op_ssl_handshake, ec);
}
return;
}
@ -2407,8 +2410,8 @@ retry:
session_log(" rejected uTP connection");
#endif
if (m_alerts.should_post<peer_blocked_alert>())
m_alerts.post_alert(peer_blocked_alert(torrent_handle()
, endp.address(), peer_blocked_alert::utp_disabled));
m_alerts.emplace_alert<peer_blocked_alert>(torrent_handle()
, endp.address(), peer_blocked_alert::utp_disabled);
return;
}
@ -2419,8 +2422,8 @@ retry:
session_log(" rejected TCP connection");
#endif
if (m_alerts.should_post<peer_blocked_alert>())
m_alerts.post_alert(peer_blocked_alert(torrent_handle()
, endp.address(), peer_blocked_alert::tcp_disabled));
m_alerts.emplace_alert<peer_blocked_alert>(torrent_handle()
, endp.address(), peer_blocked_alert::tcp_disabled);
return;
}
@ -2455,8 +2458,8 @@ retry:
, local.address().to_string(ec).c_str());
#endif
if (m_alerts.should_post<peer_blocked_alert>())
m_alerts.post_alert(peer_blocked_alert(torrent_handle()
, endp.address(), peer_blocked_alert::invalid_local_interface));
m_alerts.emplace_alert<peer_blocked_alert>(torrent_handle()
, endp.address(), peer_blocked_alert::invalid_local_interface);
return;
}
}
@ -2478,8 +2481,8 @@ retry:
session_log("filtered blocked ip");
#endif
if (m_alerts.should_post<peer_blocked_alert>())
m_alerts.post_alert(peer_blocked_alert(torrent_handle()
, endp.address(), peer_blocked_alert::ip_filter));
m_alerts.emplace_alert<peer_blocked_alert>(torrent_handle()
, endp.address(), peer_blocked_alert::ip_filter);
return;
}
@ -2518,11 +2521,10 @@ retry:
{
if (m_alerts.should_post<peer_disconnected_alert>())
{
m_alerts.post_alert(
peer_disconnected_alert(torrent_handle(), endp, peer_id()
m_alerts.emplace_alert<peer_disconnected_alert>(torrent_handle(), endp, peer_id()
, op_bittorrent, s->type()
, error_code(errors::too_many_connections, get_libtorrent_category())
, close_no_reason));
, close_no_reason);
}
#if defined TORRENT_LOGGING
session_log("number of connections limit exceeded (conns: %d, limit: %d, slack: %d), connection rejected"
@ -2561,7 +2563,7 @@ retry:
m_stats_counters.inc_stats_counter(counters::incoming_connections);
if (m_alerts.should_post<incoming_connection_alert>())
m_alerts.post_alert(incoming_connection_alert(s->type(), endp));
m_alerts.emplace_alert<incoming_connection_alert>(s->type(), endp);
setup_socket_buffers(*s);
@ -2615,8 +2617,8 @@ retry:
if (e)
{
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert("socks5", listen_failed_alert::accept, e
, listen_failed_alert::socks5));
m_alerts.emplace_alert<listen_failed_alert>("socks5", listen_failed_alert::accept, e
, listen_failed_alert::socks5);
return;
}
open_new_incoming_socks_connection();
@ -2662,14 +2664,6 @@ retry:
if (i != m_connections.end()) m_connections.erase(i);
}
// implements alert_dispatcher
bool session_impl::post_alert(alert* a)
{
if (!m_alerts.should_post(a)) return false;
m_alerts.post_alert_ptr(a);
return true;
}
void session_impl::set_peer_id(peer_id const& id)
{
m_peer_id = id;
@ -3033,16 +3027,16 @@ retry:
&& m_stat.download_ip_overhead() >= down_limit
&& m_alerts.should_post<performance_alert>())
{
m_alerts.post_alert(performance_alert(torrent_handle()
, performance_alert::download_limit_too_low));
m_alerts.emplace_alert<performance_alert>(torrent_handle()
, performance_alert::download_limit_too_low);
}
if (up_limit > 0
&& m_stat.upload_ip_overhead() >= up_limit
&& m_alerts.should_post<performance_alert>())
{
m_alerts.post_alert(performance_alert(torrent_handle()
, performance_alert::upload_limit_too_low));
m_alerts.emplace_alert<performance_alert>(torrent_handle()
, performance_alert::upload_limit_too_low);
}
}
@ -3921,8 +3915,8 @@ retry:
// assume 20 kB/s
max_upload_rate = (std::max)(20000, m_peak_up_rate + 10000);
if (m_alerts.should_post<performance_alert>())
m_alerts.post_alert(performance_alert(torrent_handle()
, performance_alert::bittyrant_with_no_uplimit));
m_alerts.emplace_alert<performance_alert>(torrent_handle()
, performance_alert::bittyrant_with_no_uplimit);
}
int allowed_upload_slots = unchoke_sort(peers, max_upload_rate
@ -4298,7 +4292,7 @@ retry:
char buf[1024];
vsnprintf(buf, sizeof(buf), fmt, v);
m_alerts.post_alert(log_alert(buf));
m_alerts.emplace_alert<log_alert>(buf);
}
void session_impl::log_all_torrents(peer_connection* p)
@ -4345,31 +4339,33 @@ retry:
TORRENT_ASSERT(is_single_thread());
std::auto_ptr<state_update_alert> alert(new state_update_alert());
std::vector<torrent*>& state_updates
= m_torrent_lists[aux::session_impl::torrent_state_updates];
alert->status.reserve(state_updates.size());
#if TORRENT_USE_ASSERTS
m_posting_torrent_updates = true;
#endif
std::vector<torrent_status> status;
status.reserve(state_updates.size());
// TODO: it might be a nice feature here to limit the number of torrents
// to send in a single update. By just posting the first n torrents, they
// would nicely be round-robined because the torrent lists are always
// pushed back
// pushed back. Perhaps the status_update_alert could even have a fixed
// array of n entries rather than a vector, to further improve memory
// locality.
for (std::vector<torrent*>::iterator i = state_updates.begin()
, end(state_updates.end()); i != end; ++i)
{
torrent* t = *i;
TORRENT_ASSERT(t->m_links[aux::session_impl::torrent_state_updates].in_list());
alert->status.push_back(torrent_status());
status.push_back(torrent_status());
// querying accurate download counters may require
// the torrent to be loaded. Loading a torrent, and evicting another
// one will lead to calling state_updated(), which screws with
// this list while we're working on it, and break things
t->status(&alert->status.back(), flags);
t->status(&status.back(), flags);
t->clear_in_state_update();
}
state_updates.clear();
@ -4378,15 +4374,11 @@ retry:
m_posting_torrent_updates = false;
#endif
m_alerts.post_alert_ptr(alert.release());
m_alerts.emplace_alert<state_update_alert>(status);
}
void session_impl::post_session_stats()
{
std::auto_ptr<session_stats_alert> alert(new session_stats_alert());
std::vector<boost::uint64_t>& values = alert->values;
values.resize(counters::num_counters, 0);
m_disk_thread.update_stats_counters(m_stats_counters);
m_stats_counters.set_value(counters::sent_ip_overhead_bytes
@ -4405,24 +4397,20 @@ retry:
m_stats_counters.set_value(counters::limiter_down_bytes
, m_download_rate.queued_bytes());
for (int i = 0; i < counters::num_counters; ++i)
values[i] = m_stats_counters[i];
alert->timestamp = total_microseconds(clock_type::now() - m_created);
m_alerts.post_alert_ptr(alert.release());
m_alerts.emplace_alert<session_stats_alert>(m_stats_counters);
}
void session_impl::post_dht_stats()
{
std::auto_ptr<dht_stats_alert> alert(new dht_stats_alert());
std::vector<dht_lookup> requests;
std::vector<dht_routing_bucket> table;
#ifndef TORRENT_DISABLE_DHT
if (m_dht)
m_dht->dht_status(alert->routing_table, alert->active_requests);
m_dht->dht_status(table, requests);
#endif
m_alerts.post_alert_ptr(alert.release());
m_alerts.emplace_alert<dht_stats_alert>(table, requests);
}
std::vector<torrent_handle> session_impl::get_torrents() const
@ -4466,7 +4454,7 @@ retry:
if (j->error.ec)
{
ec = j->error.ec;
m_alerts.post_alert(add_torrent_alert(handle, *params, ec));
m_alerts.emplace_alert<add_torrent_alert>(handle, *params, ec);
}
else
{
@ -4495,7 +4483,7 @@ retry:
, error_code& ec)
{
torrent_handle h = add_torrent_impl(p, ec);
m_alerts.post_alert(add_torrent_alert(h, p, ec));
m_alerts.emplace_alert<add_torrent_alert>(h, p, ec);
return h;
}
@ -4747,7 +4735,7 @@ retry:
? params.url : params.uuid, torrent_ptr));
if (m_alerts.should_post<torrent_added_alert>())
m_alerts.post_alert(torrent_added_alert(torrent_ptr->get_handle()));
m_alerts.emplace_alert<torrent_added_alert>(torrent_ptr->get_handle());
// recalculate auto-managed torrents sooner (or put it off)
// if another torrent will be added within one second from now
@ -4861,7 +4849,7 @@ retry:
boost::shared_ptr<torrent> tptr = h.m_torrent.lock();
if (!tptr) return;
m_alerts.post_alert(torrent_removed_alert(tptr->get_handle(), tptr->info_hash()));
m_alerts.emplace_alert<torrent_removed_alert>(tptr->get_handle(), tptr->info_hash());
remove_torrent_impl(tptr, options);
@ -4898,8 +4886,8 @@ retry:
if (!t.delete_files())
{
if (m_alerts.should_post<torrent_delete_failed_alert>())
m_alerts.post_alert(torrent_delete_failed_alert(t.get_handle()
, error_code(), t.torrent_file().info_hash()));
m_alerts.emplace_alert<torrent_delete_failed_alert>(t.get_handle()
, error_code(), t.torrent_file().info_hash());
}
}
@ -5206,7 +5194,7 @@ retry:
t->do_connect_boost();
if (m_alerts.should_post<lsd_peer_alert>())
m_alerts.post_alert(lsd_peer_alert(t->get_handle(), peer));
m_alerts.emplace_alert<lsd_peer_alert>(t->get_handle(), peer);
}
void session_impl::on_port_map_log(
@ -5215,7 +5203,7 @@ retry:
TORRENT_ASSERT(map_transport >= 0 && map_transport <= 1);
// log message
if (m_alerts.should_post<portmap_log_alert>())
m_alerts.post_alert(portmap_log_alert(map_transport, msg));
m_alerts.emplace_alert<portmap_log_alert>(map_transport, msg);
}
void session_impl::on_port_mapping(int mapping, address const& ip, int port
@ -5229,8 +5217,8 @@ retry:
{
m_external_udp_port = port;
if (m_alerts.should_post<portmap_alert>())
m_alerts.post_alert(portmap_alert(mapping, port
, map_transport));
m_alerts.emplace_alert<portmap_alert>(mapping, port
, map_transport);
return;
}
@ -5248,22 +5236,22 @@ retry:
m_listen_sockets.front().external_port = port;
}
if (m_alerts.should_post<portmap_alert>())
m_alerts.post_alert(portmap_alert(mapping, port
, map_transport));
m_alerts.emplace_alert<portmap_alert>(mapping, port
, map_transport);
return;
}
if (ec)
{
if (m_alerts.should_post<portmap_error_alert>())
m_alerts.post_alert(portmap_error_alert(mapping
, map_transport, ec));
m_alerts.emplace_alert<portmap_error_alert>(mapping
, map_transport, ec);
}
else
{
if (m_alerts.should_post<portmap_alert>())
m_alerts.post_alert(portmap_alert(mapping, port
, map_transport));
m_alerts.emplace_alert<portmap_alert>(mapping, port
, map_transport);
}
}
@ -5402,7 +5390,7 @@ retry:
void on_bootstrap(alert_manager& alerts)
{
if (alerts.should_post<dht_bootstrap_alert>())
alerts.post_alert(dht_bootstrap_alert());
alerts.emplace_alert<dht_bootstrap_alert>();
}
void session_impl::start_dht(entry const& startup_state)
@ -5470,8 +5458,8 @@ retry:
if (e)
{
if (m_alerts.should_post<dht_error_alert>())
m_alerts.post_alert(dht_error_alert(
dht_error_alert::hostname_lookup, e));
m_alerts.emplace_alert<dht_error_alert>(
dht_error_alert::hostname_lookup, e);
return;
}
@ -5491,7 +5479,7 @@ retry:
, dht::item const& i)
{
TORRENT_ASSERT(!i.is_mutable());
m_alerts.post_alert(dht_immutable_item_alert(target, i.value()));
m_alerts.emplace_alert<dht_immutable_item_alert>(target, i.value());
}
void session_impl::dht_get_immutable_item(sha1_hash const& target)
@ -5505,8 +5493,8 @@ retry:
void session_impl::get_mutable_callback(dht::item const& i)
{
TORRENT_ASSERT(i.is_mutable());
m_alerts.post_alert(dht_mutable_item_alert(i.pk(), i.sig(), i.seq()
, i.salt(), i.value()));
m_alerts.emplace_alert<dht_mutable_item_alert>(i.pk(), i.sig(), i.seq()
, i.salt(), i.value());
}
// key is a 32-byte binary string, the public key to look up.
@ -5522,7 +5510,7 @@ retry:
void on_dht_put(alert_manager& alerts, sha1_hash target)
{
if (alerts.should_post<dht_put_alert>())
alerts.post_alert(dht_put_alert(target));
alerts.emplace_alert<dht_put_alert>(target);
}
void session_impl::dht_put_item(entry data, sha1_hash target)
@ -5545,7 +5533,7 @@ retry:
i.assign(value, salt, seq, pk.data(), sig.data());
if (alerts.should_post<dht_put_alert>())
alerts.post_alert(dht_put_alert(pk, sig, salt, seq));
alerts.emplace_alert<dht_put_alert>(pk, sig, salt, seq);
}
void session_impl::dht_put_mutable_item(boost::array<char, 32> key
@ -5810,8 +5798,8 @@ retry:
>= allowed_upload_slots / 2)
{
if (m_alerts.should_post<performance_alert>())
m_alerts.post_alert(performance_alert(torrent_handle()
, performance_alert::too_many_optimistic_unchoke_slots));
m_alerts.emplace_alert<performance_alert>(torrent_handle()
, performance_alert::too_many_optimistic_unchoke_slots);
}
}
@ -5829,8 +5817,8 @@ retry:
&& cache_size > 5
&& m_alerts.should_post<performance_alert>())
{
m_alerts.post_alert(performance_alert(torrent_handle()
, performance_alert::too_high_disk_queue_limit));
m_alerts.emplace_alert<performance_alert>(torrent_handle()
, performance_alert::too_high_disk_queue_limit);
}
}
@ -5961,7 +5949,7 @@ retry:
if (ec)
{
if (m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec));
m_alerts.emplace_alert<udp_error_alert>(udp::endpoint(), ec);
}
#ifdef TORRENT_USE_OPENSSL
@ -5969,7 +5957,7 @@ retry:
if (ec)
{
if (m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(udp::endpoint(), ec));
m_alerts.emplace_alert<udp_error_alert>(udp::endpoint(), ec);
}
#endif
}
@ -6163,6 +6151,24 @@ retry:
}
}
void session_impl::update_alert_mask()
{
m_alerts.set_alert_mask(m_settings.get_int(settings_pack::alert_mask));
}
void session_impl::pop_alerts(std::vector<alert*>* alerts)
{
int num_resume = 0;
m_alerts.get_all(*alerts, num_resume);
if (num_resume > 0)
{
// we can only issue more resume data jobs from
// the network thread
m_io_service.post(boost::bind(&session_impl::async_resume_dispatched
, this, num_resume));
}
}
#ifndef TORRENT_NO_DEPRECATE
void session_impl::update_rate_limit_utp()
{
@ -6194,49 +6200,62 @@ retry:
void session_impl::update_ignore_rate_limits_on_local_network()
{
init_peer_class_filter(m_settings.get_bool(settings_pack::ignore_limits_on_local_network));
init_peer_class_filter(
m_settings.get_bool(settings_pack::ignore_limits_on_local_network));
}
// this function is called on the user's thread
// not the network thread
void session_impl::pop_alerts()
{
// if we don't have any alerts in our local cache, we have to ask
// the alert_manager for more. It will swap our vector with its and
// destruct eny left-over alerts in there.
if (m_alert_pointer_pos >= m_alert_pointers.size())
{
pop_alerts(&m_alert_pointers);
m_alert_pointer_pos = 0;
}
}
alert const* session_impl::pop_alert()
{
if (m_alert_pointer_pos >= m_alert_pointers.size())
{
pop_alerts();
if (m_alert_pointers.empty())
return NULL;
}
if (m_alert_pointers.empty()) return NULL;
// clone here to be backwards compatible, to make the client delete the
// alert object
return m_alert_pointers[m_alert_pointer_pos++];
}
void session_impl::pop_alerts(std::deque<alert*>* alerts)
{
alerts->clear();
if (m_alert_pointer_pos >= m_alert_pointers.size())
{
pop_alerts();
if (m_alert_pointers.empty())
return;
}
for (std::vector<alert*>::iterator i = m_alert_pointers.begin()
+ m_alert_pointer_pos, end(m_alert_pointers.end());
i != end; ++i)
{
alerts->push_back((*i)->clone().release());
}
m_alert_pointer_pos = m_alert_pointers.size();
}
#endif
void session_impl::update_alert_mask()
{
m_alerts.set_alert_mask(m_settings.get_int(settings_pack::alert_mask));
}
void session_impl::set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun)
{
m_alerts.set_dispatch_function(fun);
}
// this function is called on the user's thread
// not the network thread
std::auto_ptr<alert> session_impl::pop_alert()
{
int num_resume = 0;
std::auto_ptr<alert> ret = m_alerts.get(num_resume);
if (num_resume > 0)
{
// we can only issue more resume data jobs from
// the network thread
m_io_service.post(boost::bind(&session_impl::async_resume_dispatched
, this, num_resume));
}
return ret;
}
// this function is called on the user's thread
// not the network thread
void session_impl::pop_alerts(std::deque<alert*>* alerts)
{
int num_resume = 0;
m_alerts.get_all(alerts, num_resume);
// we can only issue more resume data jobs from
// the network thread
m_io_service.post(boost::bind(&session_impl::async_resume_dispatched
, this, num_resume));
}
alert const* session_impl::wait_for_alert(time_duration max_wait)
alert* session_impl::wait_for_alert(time_duration max_wait)
{
return m_alerts.wait_for_alert(max_wait);
}
@ -6264,14 +6283,14 @@ retry:
error_code ec;
m_lsd->start(ec);
if (ec && m_alerts.should_post<lsd_error_alert>())
m_alerts.post_alert(lsd_error_alert(ec));
m_alerts.emplace_alert<lsd_error_alert>(ec);
}
#if defined TORRENT_LOGGING
void session_impl::on_lsd_log(char const* log)
{
if (!m_alerts.should_post<log_alert>()) return;
m_alerts.post_alert(log_alert(log));
m_alerts.emplace_alert<log_alert>(log);
}
#endif
@ -6414,6 +6433,26 @@ retry:
set_external_address(ip, source_dht, source);
}
void session_impl::get_peers(sha1_hash const& ih)
{
if (!m_alerts.should_post<dht_get_peers_alert>()) return;
m_alerts.emplace_alert<dht_get_peers_alert>(ih);
}
void session_impl::announce(sha1_hash const& ih, address const& addr
, int port)
{
if (!m_alerts.should_post<dht_announce_alert>()) return;
m_alerts.emplace_alert<dht_announce_alert>(addr, port, ih);
}
void session_impl::outgoing_get_peers(sha1_hash const& target
, sha1_hash const& sent_target, udp::endpoint const& ep)
{
if (!m_alerts.should_post<dht_outgoing_get_peers_alert>()) return;
m_alerts.emplace_alert<dht_outgoing_get_peers_alert>(target, sent_target, ep);
}
void session_impl::set_external_address(address const& ip
, int source_type, address const& source)
{
@ -6429,7 +6468,7 @@ retry:
#endif
if (m_alerts.should_post<external_ip_alert>())
m_alerts.post_alert(external_ip_alert(ip));
m_alerts.emplace_alert<external_ip_alert>(ip);
for (torrent_map::iterator i = m_torrents.begin()
, end(m_torrents.end()); i != end; ++i)

View File

@ -546,8 +546,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<metadata_received_alert>())
{
m_ses.alerts().post_alert(metadata_received_alert(
get_handle()));
m_ses.alerts().emplace_alert<metadata_received_alert>(
get_handle());
}
state_updated();
@ -635,7 +635,7 @@ namespace libtorrent
m_ses.remove_torrent_impl(me, 0);
if (alerts().should_post<torrent_update_alert>())
alerts().post_alert(torrent_update_alert(get_handle(), info_hash(), tf->info_hash()));
alerts().emplace_alert<torrent_update_alert>(get_handle(), info_hash(), tf->info_hash());
m_torrent_file = tf;
m_info_hash = tf->info_hash();
@ -693,8 +693,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<metadata_received_alert>())
{
m_ses.alerts().post_alert(metadata_received_alert(
get_handle()));
m_ses.alerts().emplace_alert<metadata_received_alert>(
get_handle());
}
state_updated();
@ -772,7 +772,7 @@ namespace libtorrent
debug_log("resume data rejected: %s pos: %d", ec.message().c_str(), pos);
#endif
if (m_ses.alerts().should_post<fastresume_rejected_alert>())
m_ses.alerts().post_alert(fastresume_rejected_alert(get_handle(), ec, "", 0));
m_ses.alerts().emplace_alert<fastresume_rejected_alert>(get_handle(), ec, "", (char const*)0);
}
}
@ -911,8 +911,8 @@ namespace libtorrent
if (m_abort || m_deleted)
{
// failed
m_ses.alerts().post_alert(read_piece_alert(
get_handle(), piece, error_code(boost::system::errc::operation_canceled, system_category())));
m_ses.alerts().emplace_alert<read_piece_alert>(
get_handle(), piece, error_code(boost::system::errc::operation_canceled, system_category()));
return;
}
@ -936,8 +936,8 @@ namespace libtorrent
if (!need_loaded())
{
rp->piece_data.reset();
m_ses.alerts().post_alert(read_piece_alert(
get_handle(), r.piece, rp->piece_data, 0));
m_ses.alerts().emplace_alert<read_piece_alert>(
get_handle(), r.piece, rp->piece_data, 0);
delete rp;
return;
}
@ -1125,8 +1125,8 @@ namespace libtorrent
if (j->error.ec == error_code(boost::system::errc::not_enough_memory, generic_category()))
{
if (alerts().should_post<file_error_alert>())
alerts().post_alert(file_error_alert(j->error.ec
, resolve_filename(j->error.file), j->error.operation_str(), get_handle()));
alerts().emplace_alert<file_error_alert>(j->error.ec
, resolve_filename(j->error.file), j->error.operation_str(), get_handle());
if (c) c->disconnect(errors::no_memory, op_file);
return;
}
@ -1135,8 +1135,8 @@ namespace libtorrent
// notify the user of the error
if (alerts().should_post<file_error_alert>())
alerts().post_alert(file_error_alert(j->error.ec
, resolve_filename(j->error.file), j->error.operation_str(), get_handle()));
alerts().emplace_alert<file_error_alert>(j->error.ec
, resolve_filename(j->error.file), j->error.operation_str(), get_handle());
// put the torrent in an error-state
set_error(j->error.ec, j->error.file);
@ -1220,13 +1220,13 @@ namespace libtorrent
int size = m_torrent_file->piece_size(r.piece);
if (rp->fail)
{
m_ses.alerts().post_alert(read_piece_alert(
get_handle(), r.piece, rp->error));
m_ses.alerts().emplace_alert<read_piece_alert>(
get_handle(), r.piece, rp->error);
}
else
{
m_ses.alerts().post_alert(read_piece_alert(
get_handle(), r.piece, rp->piece_data, size));
m_ses.alerts().emplace_alert<read_piece_alert>(
get_handle(), r.piece, rp->piece_data, size);
}
delete rp;
}
@ -1650,7 +1650,7 @@ namespace libtorrent
// if all went well, set the torrent ssl context to this one
m_ssl_ctx = ctx;
// tell the client we need a cert for this torrent
alerts().post_alert(torrent_need_cert_alert(get_handle()));
alerts().emplace_alert<torrent_need_cert_alert>(get_handle());
#else
set_error(asio::error::operation_not_supported, error_file_ssl_ctx);
pause();
@ -1765,7 +1765,7 @@ namespace libtorrent
if (ev && m_ses.alerts().should_post<fastresume_rejected_alert>())
{
error_code ec = error_code(ev, get_libtorrent_category());
m_ses.alerts().post_alert(fastresume_rejected_alert(get_handle(), ec, "", 0));
m_ses.alerts().emplace_alert<fastresume_rejected_alert>(get_handle(), ec, "", (char const*)0);
}
if (ev)
@ -2314,8 +2314,8 @@ namespace libtorrent
if ((j->error || j->ret != 0) && m_resume_data
&& m_ses.alerts().should_post<fastresume_rejected_alert>())
{
m_ses.alerts().post_alert(fastresume_rejected_alert(get_handle(), j->error.ec
, resolve_filename(j->error.file), j->error.operation_str()));
m_ses.alerts().emplace_alert<fastresume_rejected_alert>(get_handle(), j->error.ec
, resolve_filename(j->error.file), j->error.operation_str());
}
#if defined TORRENT_LOGGING
@ -2637,8 +2637,8 @@ namespace libtorrent
m_checking_piece = 0;
m_num_checked_pieces = 0;
if (m_ses.alerts().should_post<file_error_alert>())
m_ses.alerts().post_alert(file_error_alert(j->error.ec,
resolve_filename(j->error.file), j->error.operation_str(), get_handle()));
m_ses.alerts().emplace_alert<file_error_alert>(j->error.ec,
resolve_filename(j->error.file), j->error.operation_str(), get_handle());
#if defined TORRENT_LOGGING
debug_log("on_piece_hashed, fatal disk error: (%d) %s", j->error.ec.value(), j->error.ec.message().c_str());
@ -2699,7 +2699,7 @@ namespace libtorrent
// we are in graceful pause mode, and we just completed the last outstanding job.
// now we can be considered paused
if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle()));
alerts().emplace_alert<torrent_paused_alert>(get_handle());
}
// we paused the checking
@ -2910,8 +2910,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<dht_reply_alert>())
{
m_ses.alerts().post_alert(dht_reply_alert(
get_handle(), peers.size()));
m_ses.alerts().emplace_alert<dht_reply_alert>(
get_handle(), peers.size());
}
if (torrent_file().priv() || (torrent_file().is_i2p()
@ -2936,7 +2936,7 @@ namespace libtorrent
if (m_trackers.empty())
{
#if defined TORRENT_LOGGING
debug_log("*** announce_with_tracker: no trackers");
debug_log("*** announce: no trackers");
#endif
return;
}
@ -2948,7 +2948,7 @@ namespace libtorrent
if (e != tracker_request::stopped && !m_announce_to_trackers)
{
#if defined TORRENT_LOGGING
debug_log("*** announce_with_tracker: event != stopped && !m_announce_to_trackers");
debug_log("*** announce: event != stopped && !m_announce_to_trackers");
#endif
return;
}
@ -2957,7 +2957,7 @@ namespace libtorrent
if (e != tracker_request::stopped && !m_allow_peers)
{
#if defined TORRENT_LOGGING
debug_log("*** announce_with_tracker: event != stopped && !m_allow_peers");
debug_log("*** announce: event != stopped && !m_allow_peers");
#endif
return;
}
@ -3009,11 +3009,11 @@ namespace libtorrent
{
announce_entry& ae = m_trackers[i];
#if defined TORRENT_LOGGING
debug_log("*** announce with tracker: considering \"%s\" "
"[ announce_to_all_tiers: %d announce_to_all_trackers: %d"
" i->tier: %d tier: %d "
" is_working: %d fails: %d fail_limit: %d updating: %d"
" can_announce: %d sent_announce: %d ]"
debug_log("*** tracker: \"%s\" "
"[ tiers: %d trackers: %d"
" i->tier: %d tier: %d"
" working: %d fails: %d limit: %d upd: %d"
" can: %d sent: %d ]"
, ae.url.c_str(), settings().get_bool(settings_pack::announce_to_all_tiers)
, settings().get_bool(settings_pack::announce_to_all_trackers)
, ae.tier, tier, ae.is_working(), ae.fails, ae.fail_limit
@ -3064,9 +3064,8 @@ namespace libtorrent
ae.next_announce = now + minutes(10);
if (m_ses.alerts().should_post<anonymous_mode_alert>())
{
m_ses.alerts().post_alert(
anonymous_mode_alert(get_handle()
, anonymous_mode_alert::tracker_not_anonymous, req.url));
m_ses.alerts().emplace_alert<anonymous_mode_alert>(get_handle()
, anonymous_mode_alert::tracker_not_anonymous, req.url);
}
continue;
}
@ -3082,9 +3081,8 @@ namespace libtorrent
ae.next_announce = now + minutes(10);
if (m_ses.alerts().should_post<anonymous_mode_alert>())
{
m_ses.alerts().post_alert(
anonymous_mode_alert(get_handle()
, anonymous_mode_alert::tracker_not_anonymous, req.url));
m_ses.alerts().emplace_alert<anonymous_mode_alert>(get_handle()
, anonymous_mode_alert::tracker_not_anonymous, req.url);
}
continue;
}
@ -3117,8 +3115,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<tracker_announce_alert>())
{
m_ses.alerts().post_alert(
tracker_announce_alert(get_handle(), req.url, req.event));
m_ses.alerts().emplace_alert<tracker_announce_alert>(
get_handle(), req.url, req.event);
}
sent_announce = true;
@ -3158,7 +3156,7 @@ namespace libtorrent
INVARIANT_CHECK;
if (m_ses.alerts().should_post<tracker_warning_alert>())
m_ses.alerts().post_alert(tracker_warning_alert(get_handle(), req.url, msg));
m_ses.alerts().emplace_alert<tracker_warning_alert>(get_handle(), req.url, msg);
}
void torrent::tracker_scrape_response(tracker_request const& req
@ -3181,8 +3179,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<scrape_reply_alert>())
{
m_ses.alerts().post_alert(scrape_reply_alert(
get_handle(), incomplete, complete, req.url));
m_ses.alerts().emplace_alert<scrape_reply_alert>(
get_handle(), incomplete, complete, req.url);
}
}
@ -3260,8 +3258,8 @@ namespace libtorrent
{
ae->trackerid = resp.trackerid;
if (m_ses.alerts().should_post<trackerid_alert>())
m_ses.alerts().post_alert(trackerid_alert(get_handle()
, r.url, resp.trackerid));
m_ses.alerts().emplace_alert<trackerid_alert>(get_handle()
, r.url, resp.trackerid);
}
update_scrape_state();
@ -3374,12 +3372,12 @@ namespace libtorrent
if (m_ses.alerts().should_post<tracker_reply_alert>())
{
m_ses.alerts().post_alert(tracker_reply_alert(
m_ses.alerts().emplace_alert<tracker_reply_alert>(
get_handle(), resp.peers.size() + resp.peers4.size()
#if TORRENT_USE_IPV6
+ resp.peers6.size()
#endif
, r.url));
, r.url);
}
m_got_tracker_response = true;
@ -3588,8 +3586,8 @@ namespace libtorrent
debug_log("blocked ip from tracker: %s", host.address().to_string(ec).c_str());
#endif
if (m_ses.alerts().should_post<peer_blocked_alert>())
m_ses.alerts().post_alert(peer_blocked_alert(get_handle()
, host.address(), peer_blocked_alert::ip_filter));
m_ses.alerts().emplace_alert<peer_blocked_alert>(get_handle()
, host.address(), peer_blocked_alert::ip_filter);
return;
}
@ -4116,7 +4114,7 @@ namespace libtorrent
state_updated();
if (m_ses.alerts().should_post<piece_finished_alert>())
m_ses.alerts().post_alert(piece_finished_alert(get_handle(), index));
m_ses.alerts().emplace_alert<piece_finished_alert>(get_handle(), index);
// update m_file_progress (if we have one)
if (!m_file_progress.empty())
@ -4144,8 +4142,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<file_completed_alert>())
{
// this file just completed, post alert
m_ses.alerts().post_alert(file_completed_alert(get_handle()
, file_index));
m_ses.alerts().emplace_alert<file_completed_alert>(get_handle()
, file_index);
}
}
}
@ -4289,7 +4287,7 @@ namespace libtorrent
inc_stats_counter(counters::num_piece_failed);
if (m_ses.alerts().should_post<hash_failed_alert>())
m_ses.alerts().post_alert(hash_failed_alert(get_handle(), index));
m_ses.alerts().emplace_alert<hash_failed_alert>(get_handle(), index);
std::vector<int>::iterator i = std::lower_bound(m_predictive_pieces.begin()
, m_predictive_pieces.end(), index);
@ -4392,8 +4390,8 @@ namespace libtorrent
{
peer_id pid(0);
if (p->connection) pid = p->connection->pid();
m_ses.alerts().post_alert(peer_ban_alert(
get_handle(), p->ip(), pid));
m_ses.alerts().emplace_alert<peer_ban_alert>(
get_handle(), p->ip(), pid);
}
// mark the peer as banned
@ -4786,7 +4784,7 @@ namespace libtorrent
{
TORRENT_ASSERT(m_abort);
if (alerts().should_post<cache_flushed_alert>())
alerts().post_alert(cache_flushed_alert(get_handle()));
alerts().emplace_alert<cache_flushed_alert>(get_handle());
}
m_storage.reset();
@ -4877,12 +4875,12 @@ namespace libtorrent
if (j->ret != 0)
{
if (alerts().should_post<torrent_delete_failed_alert>())
alerts().post_alert(torrent_delete_failed_alert(get_handle()
, j->error.ec, m_torrent_file->info_hash()));
alerts().emplace_alert<torrent_delete_failed_alert>(get_handle()
, j->error.ec, m_torrent_file->info_hash());
}
else
{
alerts().post_alert(torrent_deleted_alert(get_handle(), m_torrent_file->info_hash()));
alerts().emplace_alert<torrent_deleted_alert>(get_handle(), m_torrent_file->info_hash());
}
}
@ -4895,15 +4893,15 @@ namespace libtorrent
if (!j->buffer)
{
alerts().post_alert(save_resume_data_failed_alert(get_handle(), j->error.ec));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle(), j->error.ec);
return;
}
m_need_save_resume_data = false;
m_last_saved_resume = m_ses.session_time();
write_resume_data(*((entry*)j->buffer));
alerts().post_alert(save_resume_data_alert(boost::shared_ptr<entry>((entry*)j->buffer)
, get_handle()));
alerts().emplace_alert<save_resume_data_alert>(
boost::shared_ptr<entry>((entry*)j->buffer), get_handle());
const_cast<disk_io_job*>(j)->buffer = 0;
state_updated();
}
@ -4916,14 +4914,14 @@ namespace libtorrent
if (j->ret == 0)
{
if (alerts().should_post<file_renamed_alert>())
alerts().post_alert(file_renamed_alert(get_handle(), j->buffer, j->piece));
alerts().emplace_alert<file_renamed_alert>(get_handle(), j->buffer, j->piece);
m_torrent_file->rename_file(j->piece, j->buffer);
}
else
{
if (alerts().should_post<file_rename_failed_alert>())
alerts().post_alert(file_rename_failed_alert(get_handle()
, j->piece, j->error.ec));
alerts().emplace_alert<file_rename_failed_alert>(get_handle()
, j->piece, j->error.ec);
}
}
@ -4932,7 +4930,7 @@ namespace libtorrent
TORRENT_ASSERT(is_single_thread());
if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle()));
alerts().emplace_alert<torrent_paused_alert>(get_handle());
}
// TODO: 2 the tracker login feature should probably be deprecated
@ -4998,8 +4996,8 @@ namespace libtorrent
// failed
if (flags & torrent_handle::alert_when_available)
{
m_ses.alerts().post_alert(read_piece_alert(
get_handle(), piece, error_code(boost::system::errc::operation_canceled, system_category())));
m_ses.alerts().emplace_alert<read_piece_alert>(
get_handle(), piece, error_code(boost::system::errc::operation_canceled, system_category()));
}
return;
}
@ -5133,8 +5131,8 @@ namespace libtorrent
else if (i->flags & torrent_handle::alert_when_available)
{
// post an empty read_piece_alert to indicate it failed
alerts().post_alert(read_piece_alert(
get_handle(), piece, error_code(boost::system::errc::operation_canceled, system_category())));
alerts().emplace_alert<read_piece_alert>(
get_handle(), piece, error_code(boost::system::errc::operation_canceled, system_category()));
}
if (has_picker()) m_picker->set_piece_priority(piece, 1);
m_time_critical_pieces.erase(i);
@ -5150,8 +5148,8 @@ namespace libtorrent
if (i->flags & torrent_handle::alert_when_available)
{
// post an empty read_piece_alert to indicate it failed
m_ses.alerts().post_alert(read_piece_alert(
get_handle(), i->piece, error_code(boost::system::errc::operation_canceled, system_category())));
m_ses.alerts().emplace_alert<read_piece_alert>(
get_handle(), i->piece, error_code(boost::system::errc::operation_canceled, system_category()));
}
if (has_picker()) m_picker->set_piece_priority(i->piece, 1);
i = m_time_critical_pieces.erase(i);
@ -5169,8 +5167,8 @@ namespace libtorrent
if (i->flags & torrent_handle::alert_when_available)
{
// post an empty read_piece_alert to indicate it failed
alerts().post_alert(read_piece_alert(
get_handle(), i->piece, error_code(boost::system::errc::operation_canceled, system_category())));
alerts().emplace_alert<read_piece_alert>(
get_handle(), i->piece, error_code(boost::system::errc::operation_canceled, system_category()));
}
i = m_time_critical_pieces.erase(i);
continue;
@ -5799,8 +5797,8 @@ namespace libtorrent
if (!m_ssl_ctx)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle()
, error_code(errors::not_an_ssl_torrent), ""));
alerts().emplace_alert<torrent_error_alert>(get_handle()
, error_code(errors::not_an_ssl_torrent), "");
return;
}
@ -5810,25 +5808,25 @@ namespace libtorrent
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, ""));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, "");
}
m_ssl_ctx->use_certificate_file(certificate, context::pem, ec);
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, certificate));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, certificate);
}
m_ssl_ctx->use_private_key_file(private_key, context::pem, ec);
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, private_key));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, private_key);
}
m_ssl_ctx->use_tmp_dh_file(dh_params, ec);
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, dh_params));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, dh_params);
}
}
@ -5840,8 +5838,8 @@ namespace libtorrent
#if BOOST_VERSION < 105400
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle()
, error_code(boost::system::errc::not_supported, system_category()), "[certificate]"));
alerts().emplace_alert<torrent_error_alert>(get_handle()
, error_code(boost::system::errc::not_supported, system_category()), "[certificate]");
#else
boost::asio::const_buffer certificate_buf(certificate.c_str(), certificate.size());
@ -5851,7 +5849,7 @@ namespace libtorrent
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, "[certificate]"));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, "[certificate]");
}
boost::asio::const_buffer private_key_buf(private_key.c_str(), private_key.size());
@ -5859,7 +5857,7 @@ namespace libtorrent
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, "[private key]"));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, "[private key]");
}
boost::asio::const_buffer dh_params_buf(dh_params.c_str(), dh_params.size());
@ -5867,7 +5865,7 @@ namespace libtorrent
if (ec)
{
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, "[dh params]"));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec, "[dh params]");
}
#endif // BOOST_VERSION
}
@ -6004,8 +6002,8 @@ namespace libtorrent
#endif
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, ec));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle()
, web->url, ec);
}
// never try it again
remove_web_seed(web);
@ -6019,9 +6017,8 @@ namespace libtorrent
#endif
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url
, error_code(libtorrent::errors::peer_banned, get_libtorrent_category())));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url
, error_code(libtorrent::errors::peer_banned, get_libtorrent_category()));
}
// never try it again
remove_web_seed(web);
@ -6036,8 +6033,7 @@ namespace libtorrent
{
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, errors::unsupported_url_protocol));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url, errors::unsupported_url_protocol);
}
// never try it again
remove_web_seed(web);
@ -6048,8 +6044,8 @@ namespace libtorrent
{
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, errors::invalid_hostname));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url
, errors::invalid_hostname);
}
// never try it again
remove_web_seed(web);
@ -6060,8 +6056,8 @@ namespace libtorrent
{
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, errors::invalid_port));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url
, errors::invalid_port);
}
// never try it again
remove_web_seed(web);
@ -6072,8 +6068,8 @@ namespace libtorrent
{
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, errors::port_blocked));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle()
, web->url, errors::port_blocked);
}
// never try it again
remove_web_seed(web);
@ -6154,8 +6150,8 @@ namespace libtorrent
{
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, e));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle()
, web->url, e);
}
// the name lookup failed for the http host. Don't try
@ -6184,8 +6180,8 @@ namespace libtorrent
{
if (m_ses.alerts().should_post<url_seed_alert>())
{
m_ses.alerts().post_alert(
url_seed_alert(get_handle(), web->url, ec));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle()
, web->url, ec);
}
remove_web_seed(web);
return;
@ -6195,8 +6191,8 @@ namespace libtorrent
&& m_ses.get_ip_filter().access(a.address()) & ip_filter::blocked)
{
if (m_ses.alerts().should_post<peer_blocked_alert>())
m_ses.alerts().post_alert(peer_blocked_alert(get_handle()
, a.address(), peer_blocked_alert::ip_filter));
m_ses.alerts().emplace_alert<peer_blocked_alert>(get_handle()
, a.address(), peer_blocked_alert::ip_filter);
return;
}
@ -6235,7 +6231,7 @@ namespace libtorrent
if (e || addrs.empty())
{
if (m_ses.alerts().should_post<url_seed_alert>())
m_ses.alerts().post_alert(url_seed_alert(get_handle(), web->url, e));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url, e);
#if defined TORRENT_LOGGING
debug_log("*** HOSTNAME LOOKUP FAILED: %s: (%d) %s"
, web->url.c_str(), e.value(), e.message().c_str());
@ -6275,8 +6271,8 @@ namespace libtorrent
&& m_ses.get_ip_filter().access(a.address()) & ip_filter::blocked)
{
if (m_ses.alerts().should_post<peer_blocked_alert>())
m_ses.alerts().post_alert(peer_blocked_alert(get_handle()
, a.address(), peer_blocked_alert::ip_filter));
m_ses.alerts().emplace_alert<peer_blocked_alert>(get_handle()
, a.address(), peer_blocked_alert::ip_filter);
return;
}
@ -6324,7 +6320,7 @@ namespace libtorrent
if (ec)
{
if (m_ses.alerts().should_post<url_seed_alert>())
m_ses.alerts().post_alert(url_seed_alert(get_handle(), web->url, ec));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url, ec);
return;
}
@ -6351,7 +6347,7 @@ namespace libtorrent
if (ec)
{
if (m_ses.alerts().should_post<url_seed_alert>())
m_ses.alerts().post_alert(url_seed_alert(get_handle(), web->url, ec));
m_ses.alerts().emplace_alert<url_seed_alert>(get_handle(), web->url, ec);
return;
}
@ -7331,8 +7327,8 @@ namespace libtorrent
// we have an i2p torrent, but we're not connected to an i2p
// SAM proxy.
if (alerts().should_post<i2p_alert>())
alerts().post_alert(i2p_alert(error_code(errors::no_i2p_router
, get_libtorrent_category())));
alerts().emplace_alert<i2p_alert>(error_code(errors::no_i2p_router
, get_libtorrent_category()));
return false;
}
@ -7484,8 +7480,8 @@ namespace libtorrent
{
if (alerts().should_post<metadata_failed_alert>())
{
alerts().post_alert(metadata_failed_alert(get_handle()
, error_code(errors::mismatching_info_hash, get_libtorrent_category())));
alerts().emplace_alert<metadata_failed_alert>(get_handle()
, error_code(errors::mismatching_info_hash, get_libtorrent_category()));
}
return false;
}
@ -7501,7 +7497,7 @@ namespace libtorrent
// failed to parse it. Pause the torrent
if (alerts().should_post<metadata_failed_alert>())
{
alerts().post_alert(metadata_failed_alert(get_handle(), ec));
alerts().emplace_alert<metadata_failed_alert>(get_handle(), ec);
}
set_error(errors::invalid_swarm_metadata, error_file_none);
pause();
@ -7512,8 +7508,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<metadata_received_alert>())
{
m_ses.alerts().post_alert(metadata_received_alert(
get_handle()));
m_ses.alerts().emplace_alert<metadata_received_alert>(
get_handle());
}
// this makes the resume data "paused" and
@ -7644,8 +7640,8 @@ namespace libtorrent
&& m_ses.get_ip_filter().access(p->remote().address()) & ip_filter::blocked)
{
if (m_ses.alerts().should_post<peer_blocked_alert>())
m_ses.alerts().post_alert(peer_blocked_alert(get_handle()
, p->remote().address(), peer_blocked_alert::ip_filter));
m_ses.alerts().emplace_alert<peer_blocked_alert>(get_handle()
, p->remote().address(), peer_blocked_alert::ip_filter);
p->disconnect(errors::banned_by_ip_filter, op_bittorrent);
return false;
}
@ -8209,8 +8205,8 @@ namespace libtorrent
if (m_ses.alerts().should_post<torrent_checked_alert>())
{
m_ses.alerts().post_alert(torrent_checked_alert(
get_handle()));
m_ses.alerts().emplace_alert<torrent_checked_alert>(
get_handle());
}
// calling pause will also trigger the auto managed
@ -8324,9 +8320,9 @@ namespace libtorrent
if (!m_storage.get())
{
if (alerts().should_post<file_rename_failed_alert>())
alerts().post_alert(file_rename_failed_alert(get_handle()
alerts().emplace_alert<file_rename_failed_alert>(get_handle()
, index, error_code(errors::session_is_closing
, get_libtorrent_category())));
, get_libtorrent_category()));
return;
}
@ -8344,8 +8340,8 @@ namespace libtorrent
if (m_abort)
{
if (alerts().should_post<storage_moved_failed_alert>())
alerts().post_alert(storage_moved_failed_alert(get_handle(), boost::asio::error::operation_aborted
, "", ""));
alerts().emplace_alert<storage_moved_failed_alert>(get_handle(), boost::asio::error::operation_aborted
, "", "");
return;
}
@ -8374,7 +8370,7 @@ namespace libtorrent
if (alerts().should_post<storage_moved_alert>())
{
alerts().post_alert(storage_moved_alert(get_handle(), m_save_path));
alerts().emplace_alert<storage_moved_alert>(get_handle(), m_save_path);
}
}
}
@ -8388,7 +8384,7 @@ namespace libtorrent
if (j->ret == piece_manager::no_error || j->ret == piece_manager::need_full_check)
{
if (alerts().should_post<storage_moved_alert>())
alerts().post_alert(storage_moved_alert(get_handle(), j->buffer));
alerts().emplace_alert<storage_moved_alert>(get_handle(), j->buffer);
m_save_path = j->buffer;
m_need_save_resume_data = true;
if (j->ret == piece_manager::need_full_check)
@ -8397,8 +8393,8 @@ namespace libtorrent
else
{
if (alerts().should_post<storage_moved_failed_alert>())
alerts().post_alert(storage_moved_failed_alert(get_handle(), j->error.ec
, resolve_filename(j->error.file), j->error.operation_str()));
alerts().emplace_alert<storage_moved_failed_alert>(get_handle(), j->error.ec
, resolve_filename(j->error.file), j->error.operation_str());
}
}
@ -8839,7 +8835,8 @@ namespace libtorrent
update_gauge();
if (alerts().should_post<torrent_error_alert>())
alerts().post_alert(torrent_error_alert(get_handle(), ec, resolve_filename(error_file)));
alerts().emplace_alert<torrent_error_alert>(get_handle(), ec
, resolve_filename(error_file));
#if defined TORRENT_LOGGING
if (ec)
@ -9007,22 +9004,22 @@ namespace libtorrent
if (!valid_metadata())
{
alerts().post_alert(save_resume_data_failed_alert(get_handle()
, errors::no_metadata));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle()
, errors::no_metadata);
return;
}
if (!m_storage.get())
{
alerts().post_alert(save_resume_data_failed_alert(get_handle()
, errors::destructing_torrent));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle()
, errors::destructing_torrent);
return;
}
if ((flags & torrent_handle::only_if_modified) && !m_need_save_resume_data)
{
alerts().post_alert(save_resume_data_failed_alert(get_handle()
, errors::resume_data_not_modified));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle()
, errors::resume_data_not_modified);
return;
}
@ -9037,14 +9034,14 @@ namespace libtorrent
{
if (!need_loaded())
{
alerts().post_alert(save_resume_data_failed_alert(get_handle()
, m_error));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle()
, m_error);
return;
}
boost::shared_ptr<entry> rd(new entry);
write_resume_data(*rd);
alerts().post_alert(save_resume_data_alert(rd, get_handle()));
alerts().emplace_alert<save_resume_data_alert>(rd, get_handle());
return;
}
@ -9059,14 +9056,15 @@ namespace libtorrent
{
if (!need_loaded())
{
alerts().post_alert(save_resume_data_failed_alert(get_handle(), m_error));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle(), m_error);
return false;
}
// storage may be NULL during shutdown
if (!m_storage)
{
TORRENT_ASSERT(m_abort);
alerts().post_alert(save_resume_data_failed_alert(get_handle(), boost::asio::error::operation_aborted));
alerts().emplace_alert<save_resume_data_failed_alert>(get_handle()
, boost::asio::error::operation_aborted);
return false;
}
inc_refcount("save_resume");
@ -9110,7 +9108,7 @@ namespace libtorrent
if (m_ses.is_aborted()) return;
if (alerts().should_post<cache_flushed_alert>())
alerts().post_alert(cache_flushed_alert(get_handle()));
alerts().emplace_alert<cache_flushed_alert>(get_handle());
}
bool torrent::is_paused() const
@ -9192,7 +9190,7 @@ namespace libtorrent
if (m_checking_piece == m_num_checked_pieces)
{
if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle()));
alerts().emplace_alert<torrent_paused_alert>(get_handle());
}
disconnect_all(errors::torrent_paused, op_bittorrent);
return;
@ -9211,7 +9209,7 @@ namespace libtorrent
else
{
if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle()));
alerts().emplace_alert<torrent_paused_alert>(get_handle());
}
disconnect_all(errors::torrent_paused, op_bittorrent);
@ -9376,7 +9374,7 @@ namespace libtorrent
#endif
if (alerts().should_post<torrent_resumed_alert>())
alerts().post_alert(torrent_resumed_alert(get_handle()));
alerts().emplace_alert<torrent_resumed_alert>(get_handle());
m_started = m_ses.session_time();
if (is_seed()) m_became_seed = m_started;
@ -9415,10 +9413,10 @@ namespace libtorrent
{
#if defined TORRENT_LOGGING
char msg[1000];
snprintf(msg, sizeof(msg), "*** update tracker timer: considering \"%s\" "
"[ announce_to_all_tiers: %d announce_to_all_trackers: %d"
" found_working: %d i->tier: %d tier: %d "
" is_working: %d fails: %d fail_limit: %d updating: %d ]"
snprintf(msg, sizeof(msg), "*** tracker: \"%s\" "
"[ tiers: %d trackers: %d"
" found: %d i->tier: %d tier: %d"
" working: %d fails: %d limit: %d upd: %d ]"
, i->url.c_str(), settings().get_bool(settings_pack::announce_to_all_tiers)
, settings().get_bool(settings_pack::announce_to_all_trackers), found_working
, i->tier, tier, i->is_working(), i->fails, i->fail_limit
@ -9660,16 +9658,16 @@ namespace libtorrent
&& m_stat.download_ip_overhead() >= down_limit
&& alerts().should_post<performance_alert>())
{
alerts().post_alert(performance_alert(get_handle()
, performance_alert::download_limit_too_low));
alerts().emplace_alert<performance_alert>(get_handle()
, performance_alert::download_limit_too_low);
}
if (up_limit > 0
&& m_stat.upload_ip_overhead() >= up_limit
&& alerts().should_post<performance_alert>())
{
alerts().post_alert(performance_alert(get_handle()
, performance_alert::upload_limit_too_low));
alerts().emplace_alert<performance_alert>(get_handle()
, performance_alert::upload_limit_too_low);
}
}
@ -9743,7 +9741,7 @@ namespace libtorrent
}
}
if (m_ses.alerts().should_post<stats_alert>())
m_ses.alerts().post_alert(stats_alert(get_handle(), tick_interval_ms, m_stat));
m_ses.alerts().emplace_alert<stats_alert>(get_handle(), tick_interval_ms, m_stat);
m_total_uploaded += m_stat.last_payload_uploaded();
m_total_downloaded += m_stat.last_payload_downloaded();
@ -10772,8 +10770,8 @@ namespace libtorrent
&& m_ses.get_ip_filter().access(adr.address()) & ip_filter::blocked)
{
if (alerts().should_post<peer_blocked_alert>())
alerts().post_alert(peer_blocked_alert(get_handle()
, adr.address(), peer_blocked_alert::ip_filter));
alerts().emplace_alert<peer_blocked_alert>(get_handle()
, adr.address(), peer_blocked_alert::ip_filter);
#ifndef TORRENT_DISABLE_EXTENSIONS
notify_extension_add_peer(adr, source, torrent_plugin::filtered);
@ -10784,8 +10782,8 @@ namespace libtorrent
if (m_ses.get_port_filter().access(adr.port()) & port_filter::blocked)
{
if (alerts().should_post<peer_blocked_alert>())
alerts().post_alert(peer_blocked_alert(get_handle()
, adr.address(), peer_blocked_alert::port_filter));
alerts().emplace_alert<peer_blocked_alert>(get_handle()
, adr.address(), peer_blocked_alert::port_filter);
#ifndef TORRENT_DISABLE_EXTENSIONS
notify_extension_add_peer(adr, source, torrent_plugin::filtered);
#endif
@ -10798,8 +10796,8 @@ namespace libtorrent
if (!settings().get_bool(settings_pack::allow_i2p_mixed) && is_i2p())
{
if (alerts().should_post<peer_blocked_alert>())
alerts().post_alert(peer_blocked_alert(get_handle()
, adr.address(), peer_blocked_alert::i2p_mixed));
alerts().emplace_alert<peer_blocked_alert>(get_handle()
, adr.address(), peer_blocked_alert::i2p_mixed);
return NULL;
}
#endif
@ -10807,8 +10805,8 @@ namespace libtorrent
if (settings().get_bool(settings_pack::no_connect_privileged_ports) && adr.port() < 1024)
{
if (alerts().should_post<peer_blocked_alert>())
alerts().post_alert(peer_blocked_alert(get_handle()
, adr.address(), peer_blocked_alert::privileged_ports));
alerts().emplace_alert<peer_blocked_alert>(get_handle()
, adr.address(), peer_blocked_alert::privileged_ports);
#ifndef TORRENT_DISABLE_EXTENSIONS
notify_extension_add_peer(adr, source, torrent_plugin::filtered);
#endif
@ -10927,8 +10925,8 @@ namespace libtorrent
{
for (std::vector<address>::iterator i = banned.begin()
, end(banned.end()); i != end; ++i)
alerts().post_alert(peer_blocked_alert(get_handle(), *i
, peer_blocked_alert::ip_filter));
alerts().emplace_alert<peer_blocked_alert>(get_handle(), *i
, peer_blocked_alert::ip_filter);
}
peers_erased(st.erased);
@ -10947,8 +10945,8 @@ namespace libtorrent
{
for (std::vector<address>::iterator i = banned.begin()
, end(banned.end()); i != end; ++i)
alerts().post_alert(peer_blocked_alert(get_handle(), *i
, peer_blocked_alert::port_filter));
alerts().emplace_alert<peer_blocked_alert>(get_handle(), *i
, peer_blocked_alert::port_filter);
}
peers_erased(st.erased);
@ -11226,15 +11224,15 @@ namespace libtorrent
if (m_ses.alerts().should_post<state_changed_alert>())
{
m_ses.alerts().post_alert(state_changed_alert(get_handle()
, s, (torrent_status::state_t)m_state));
m_ses.alerts().emplace_alert<state_changed_alert>(get_handle()
, s, (torrent_status::state_t)m_state);
}
if (s == torrent_status::finished
&& alerts().should_post<torrent_finished_alert>())
{
alerts().post_alert(torrent_finished_alert(
get_handle()));
alerts().emplace_alert<torrent_finished_alert>(
get_handle());
}
m_state = s;
@ -11601,8 +11599,8 @@ namespace libtorrent
}
if (m_ses.alerts().should_post<tracker_error_alert>())
{
m_ses.alerts().post_alert(tracker_error_alert(get_handle()
, ae?ae->fails:0, response_code, r.url, ec, msg));
m_ses.alerts().emplace_alert<tracker_error_alert>(get_handle()
, ae?ae->fails:0, response_code, r.url, ec, msg);
}
}
else if (r.kind == tracker_request::scrape_request)
@ -11616,7 +11614,7 @@ namespace libtorrent
if (m_ses.alerts().should_post<scrape_failed_alert>())
{
m_ses.alerts().post_alert(scrape_failed_alert(get_handle(), r.url, ec));
m_ses.alerts().emplace_alert<scrape_failed_alert>(get_handle(), r.url, ec);
}
}
// announce to the next working tracker
@ -11637,8 +11635,8 @@ namespace libtorrent
vsnprintf(buf, sizeof(buf), fmt, v);
va_end(v);
alerts().post_alert(torrent_log_alert(
const_cast<torrent*>(this)->get_handle(), buf));
alerts().emplace_alert<torrent_log_alert>(
const_cast<torrent*>(this)->get_handle(), buf);
}
#endif

View File

@ -822,8 +822,8 @@ namespace libtorrent
{
p = parent_path(p);
// we don't want trailing slashes here
TORRENT_ASSERT(p.back() == *TORRENT_SEPARATOR);
p.pop_back();
TORRENT_ASSERT(p[p.size() - 1] == *TORRENT_SEPARATOR);
p.resize(p.size() - 1);
files.insert(p);
}
}

View File

@ -634,8 +634,8 @@ void web_peer_connection::on_receive(error_code const& error
+ (" " + m_parser.message());
if (t->alerts().should_post<url_seed_alert>())
{
t->alerts().post_alert(url_seed_alert(t->get_handle(), m_url
, error_msg));
t->alerts().emplace_alert<url_seed_alert>(t->get_handle(), m_url
, error_msg);
}
received_bytes(0, bytes_transferred);
disconnect(error_code(m_parser.status_code(), get_http_category()), op_bittorrent, 1);

View File

@ -95,8 +95,10 @@ feature launcher : none valgrind : composite ;
feature.compose <launcher>valgrind : <testing.launcher>"valgrind --tool=memcheck -v --num-callers=20 --read-var-info=yes --track-origins=yes --error-exitcode=222 --suppressions=valgrind_suppressions.txt" <use-valgrind>on ;
test-suite libtorrent :
[ run test_alert_manager.cpp ]
[ run test_resolve_links.cpp ]
[ run test_crc32.cpp ]
[ run test_heterogeneous_queue.cpp ]
[ run test_resume.cpp ]
[ run test_sliding_average.cpp ]
[ run test_socket_io.cpp ]

View File

@ -1,6 +1,7 @@
AUTOMAKE_OPTIONS = subdir-objects
test_programs = \
test_alert_manager \
test_bitfield \
test_crc32 \
test_torrent_info \
@ -20,6 +21,7 @@ test_programs = \
test_checking \
test_fast_extension \
test_hasher \
test_heterogeneous_queue \
test_http_connection \
test_ip_filter \
test_dht \

View File

@ -127,13 +127,13 @@ std::map<std::string, boost::uint64_t> get_counters(libtorrent::session& s)
s.post_session_stats();
std::map<std::string, boost::uint64_t> ret;
std::auto_ptr<alert> a = wait_for_alert(s, session_stats_alert::alert_type
alert const* a = wait_for_alert(s, session_stats_alert::alert_type
, "get_counters()");
TEST_CHECK(a.get());
if (!a.get()) return ret;
TEST_CHECK(a);
if (!a) return ret;
session_stats_alert* sa = alert_cast<session_stats_alert>(a.get());
session_stats_alert const* sa = alert_cast<session_stats_alert>(a);
if (!sa) return ret;
static std::vector<stats_metric> metrics = session_stats_metrics();
@ -142,32 +142,29 @@ std::map<std::string, boost::uint64_t> get_counters(libtorrent::session& s)
return ret;
}
std::auto_ptr<alert> wait_for_alert(lt::session& ses, int type, char const* name)
alert const* wait_for_alert(lt::session& ses, int type, char const* name)
{
std::auto_ptr<alert> ret;
time_point end = libtorrent::clock_type::now() + seconds(10);
while (!ret.get())
while (true)
{
time_point now = clock_type::now();
if (now > end) return std::auto_ptr<alert>();
if (now > end) return NULL;
ses.wait_for_alert(end - now);
std::deque<alert*> alerts;
std::vector<alert*> alerts;
ses.pop_alerts(&alerts);
for (std::deque<alert*>::iterator i = alerts.begin()
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
fprintf(stderr, "%s: %s: [%s] %s\n", aux::time_now_string(), name
, (*i)->what(), (*i)->message().c_str());
if (!ret.get() && (*i)->type() == type)
if ((*i)->type() == type)
{
ret = std::auto_ptr<alert>(*i);
return *i;
}
else
delete *i;
}
}
return ret;
return NULL;
}
int load_file(std::string const& filename, std::vector<char>& v, libtorrent::error_code& ec, int limit)
@ -254,19 +251,19 @@ void save_file(char const* filename, char const* data, int size)
bool print_alerts(lt::session& ses, char const* name
, bool allow_disconnects, bool allow_no_torrents, bool allow_failed_fastresume
, bool (*predicate)(libtorrent::alert*), bool no_output)
, bool (*predicate)(libtorrent::alert const*), bool no_output)
{
bool ret = false;
std::vector<torrent_handle> handles = ses.get_torrents();
TEST_CHECK(!handles.empty() || allow_no_torrents);
torrent_handle h;
if (!handles.empty()) h = handles[0];
std::deque<alert*> alerts;
std::vector<alert*> alerts;
ses.pop_alerts(&alerts);
for (std::deque<alert*>::iterator i = alerts.begin(); i != alerts.end(); ++i)
for (std::vector<alert*>::iterator i = alerts.begin(); i != alerts.end(); ++i)
{
if (predicate && predicate(*i)) ret = true;
if (peer_disconnected_alert* p = alert_cast<peer_disconnected_alert>(*i))
if (peer_disconnected_alert const* p = alert_cast<peer_disconnected_alert>(*i))
{
fprintf(stderr, "%s: %s: [%s] (%s): %s\n", aux::time_now_string(), name, (*i)->what(), print_endpoint(p->ip).c_str(), p->message().c_str());
}
@ -280,7 +277,7 @@ bool print_alerts(lt::session& ses, char const* name
TEST_CHECK(alert_cast<fastresume_rejected_alert>(*i) == 0 || allow_failed_fastresume);
/*
peer_error_alert* pea = alert_cast<peer_error_alert>(*i);
peer_error_alert const* pea = alert_cast<peer_error_alert>(*i);
if (pea)
{
fprintf(stderr, "%s: peer error: %s\n", aux::time_now_string(), pea->error.message().c_str());
@ -298,19 +295,18 @@ bool print_alerts(lt::session& ses, char const* name
}
*/
invalid_request_alert* ira = alert_cast<invalid_request_alert>(*i);
invalid_request_alert const* ira = alert_cast<invalid_request_alert>(*i);
if (ira)
{
fprintf(stderr, "peer error: %s\n", ira->message().c_str());
TEST_CHECK(false);
}
delete *i;
}
return ret;
}
bool listen_done = false;
bool listen_alert(libtorrent::alert* a)
bool listen_alert(libtorrent::alert const* a)
{
if (alert_cast<listen_failed_alert>(a)
|| alert_cast<listen_succeeded_alert>(a))
@ -333,9 +329,9 @@ void wait_for_listen(lt::session& ses, char const* name)
}
bool downloading_done = false;
bool downloading_alert(libtorrent::alert* a)
bool downloading_alert(libtorrent::alert const* a)
{
state_changed_alert* sc = alert_cast<state_changed_alert>(a);
state_changed_alert const* sc = alert_cast<state_changed_alert>(a);
if (sc && sc->state == torrent_status::downloading)
downloading_done = true;
return true;

View File

@ -60,7 +60,7 @@ libtorrent::udp::endpoint EXPORT rand_udp_ep();
std::map<std::string, boost::uint64_t> EXPORT get_counters(libtorrent::session& s);
std::auto_ptr<libtorrent::alert> EXPORT wait_for_alert(
libtorrent::alert const* EXPORT wait_for_alert(
libtorrent::session& ses, int type, char const* name = "");
void EXPORT print_ses_rate(float time
@ -72,7 +72,7 @@ bool EXPORT print_alerts(libtorrent::session& ses, char const* name
, bool allow_disconnects = false
, bool allow_no_torrents = false
, bool allow_failed_fastresume = false
, bool (*)(libtorrent::alert*) = 0
, bool (*)(libtorrent::alert const*) = 0
, bool no_output = false);
void EXPORT wait_for_listen(libtorrent::session& ses, char const* name);

View File

@ -190,21 +190,9 @@ void test_swarm(int flags)
ses2.remove_torrent(tor2, lt::session::delete_files);
ses3.remove_torrent(tor3, lt::session::delete_files);
std::auto_ptr<alert> a = ses1.pop_alert();
time_point end = clock_type::now() + seconds(20);
while (a.get() == 0 || alert_cast<torrent_deleted_alert>(a.get()) == 0)
{
if (ses1.wait_for_alert(end - clock_type::now()) == 0)
{
std::cerr << "wait_for_alert() expired" << std::endl;
break;
}
a = ses1.pop_alert();
assert(a.get());
std::cerr << a->message() << std::endl;
}
alert const* a = wait_for_alert(ses1, torrent_deleted_alert::alert_type, "swarm_suite");
TEST_CHECK(alert_cast<torrent_deleted_alert>(a.get()) != 0);
TEST_CHECK(alert_cast<torrent_deleted_alert>(a) != 0);
// there shouldn't be any alerts generated from now on
// make sure that the timer in wait_for_alert() works
@ -214,8 +202,13 @@ void test_swarm(int flags)
alert const* ret;
while ((ret = ses1.wait_for_alert(seconds(2))))
{
a = ses1.pop_alert();
std::cerr << ret->message() << std::endl;
std::vector<alert*> alerts;
ses1.pop_alerts(&alerts);
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
std::cerr << ret->message() << std::endl;
}
start = clock_type::now();
}

183
test/test_alert_manager.cpp Normal file
View File

@ -0,0 +1,183 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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
POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.hpp"
#include "libtorrent/alert_manager.hpp"
#include "libtorrent/torrent_handle.hpp"
#include "libtorrent/alert_types.hpp"
#include <boost/bind.hpp>
using namespace libtorrent;
void test_limit()
{
alert_manager mgr(500, 0xffffffff);
TEST_EQUAL(mgr.alert_queue_size_limit(), 500);
TEST_EQUAL(mgr.pending(), false);
// try add 600 torrent_add_alert to make sure we honor the limit of 500
// alerts.
for (int i = 0; i < 600; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
TEST_EQUAL(mgr.pending(), true);
std::vector<alert*> alerts;
int num_resume;
mgr.get_all(alerts, num_resume);
// even though we posted 600, the limit was 500
TEST_EQUAL(alerts.size(), 500);
TEST_EQUAL(mgr.pending(), false);
}
void test_priority_limit()
{
alert_manager mgr(100, 0xffffffff);
TEST_EQUAL(mgr.alert_queue_size_limit(), 100);
// this should only add 100 because of the limit
for (int i = 0; i < 200; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
// the limit is twice as high for priority alerts
for (int i = 0; i < 200; ++i)
mgr.emplace_alert<file_rename_failed_alert>(torrent_handle(), i, error_code());
std::vector<alert*> alerts;
int num_resume;
mgr.get_all(alerts, num_resume);
// even though we posted 400, the limit was 100 for half of them and
// 200 for the other half, meaning we should have 200 alerts now
TEST_EQUAL(alerts.size(), 200);
}
void test_dispatch_fun(int& cnt, std::auto_ptr<alert> a)
{
++cnt;
}
void test_dispatch_function()
{
#ifndef TORRENT_NO_DEPRECATE
int cnt = 0;
alert_manager mgr(100, 0xffffffff);
TEST_EQUAL(mgr.alert_queue_size_limit(), 100);
TEST_EQUAL(mgr.pending(), false);
for (int i = 0; i < 20; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
TEST_EQUAL(mgr.pending(), true);
mgr.set_dispatch_function(boost::bind(&test_dispatch_fun, boost::ref(cnt), _1));
TEST_EQUAL(mgr.pending(), false);
TEST_EQUAL(cnt, 20);
for (int i = 0; i < 200; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
TEST_EQUAL(mgr.pending(), false);
TEST_EQUAL(cnt, 220);
#endif
}
void test_notify_fun(int& cnt)
{
++cnt;
}
void test_notify_function()
{
int cnt = 0;
alert_manager mgr(100, 0xffffffff);
TEST_EQUAL(mgr.alert_queue_size_limit(), 100);
TEST_EQUAL(mgr.pending(), false);
for (int i = 0; i < 20; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
TEST_EQUAL(mgr.pending(), true);
// if there are queued alerts when we set the notify function,
// that counts as an edge and it's called
mgr.set_notify_function(boost::bind(&test_notify_fun, boost::ref(cnt)));
TEST_EQUAL(mgr.pending(), true);
TEST_EQUAL(cnt, 1);
// subsequent posted alerts will not cause an edge (because there are
// already alerts queued)
for (int i = 0; i < 20; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
TEST_EQUAL(mgr.pending(), true);
TEST_EQUAL(cnt, 1);
// however, if we pop all the alerts and post new ones, there will be
// and edge triggering the notify call
std::vector<alert*> alerts;
int num_resume;
mgr.get_all(alerts, num_resume);
TEST_EQUAL(mgr.pending(), false);
for (int i = 0; i < 20; ++i)
mgr.emplace_alert<torrent_added_alert>(torrent_handle());
TEST_EQUAL(mgr.pending(), true);
TEST_EQUAL(cnt, 2);
}
int test_main()
{
test_limit();
test_priority_limit();
test_dispatch_function();
test_notify_function();
// TODO: test wait_for_alert
// TODO: test num_queued_resume
// TODO: test alert_mask
return 0;
}

View File

@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/alert_types.hpp"
#include "libtorrent/disk_io_thread.hpp"
#include "libtorrent/storage.hpp"
#include "libtorrent/alert_dispatcher.hpp"
#include "libtorrent/session.hpp"
#include <boost/bind.hpp>
@ -46,16 +45,6 @@ POSSIBILITY OF SUCH DAMAGE.
using namespace libtorrent;
struct print_alert : alert_dispatcher
{
virtual bool post_alert(alert* a)
{
fprintf(stderr, "ALERT: %s\n", a->message().c_str());
delete a;
return true;
}
};
struct test_storage_impl : storage_interface
{
virtual void initialize(storage_error& ec) {}
@ -97,8 +86,7 @@ void nop() {}
#define TEST_SETUP \
io_service ios; \
print_alert ad; \
block_cache bc(0x4000, ios, boost::bind(&nop), &ad); \
block_cache bc(0x4000, ios, boost::bind(&nop)); \
aux::session_settings sett; \
file_storage fs; \
fs.add_file("a/test0", 0x4000); \
@ -113,7 +101,8 @@ void nop() {}
fs.set_num_pieces(5); \
test_storage_impl* st = new test_storage_impl; \
boost::shared_ptr<piece_manager> pm(boost::make_shared<piece_manager>(st, boost::shared_ptr<int>(new int), &fs)); \
bc.set_settings(sett); \
error_code ec; \
bc.set_settings(sett, ec); \
st->m_settings = &sett; \
disk_io_job rj; \
disk_io_job wj; \

View File

@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bencode.hpp"
#include "libtorrent/socket_io.hpp" // for hash_address
#include "libtorrent/broadcast_socket.hpp" // for supports_ipv6
#include "libtorrent/alert_dispatcher.hpp"
#include "libtorrent/performance_counters.hpp" // for counters
#include "libtorrent/random.hpp"
#include "libtorrent/ed25519.hpp"
@ -396,17 +395,6 @@ void announce_immutable_items(node_impl& node, udp::endpoint const* eps
// TEST_CHECK(items_num.find(3) != items_num.end());
}
struct print_alert : alert_dispatcher
{
virtual bool post_alert(alert* a)
{
fprintf(stderr, "ALERT: %s\n", a->message().c_str());
delete a;
return true;
}
};
int sum_distance_exp(int s, node_entry const& e, node_id const& ref)
{
return s + distance_exp(e.id, ref);
@ -445,9 +433,8 @@ int test_main()
sett.enforce_node_id = false;
address ext = address::from_string("236.0.0.1");
mock_socket s;
print_alert ad;
counters cnt;
dht::node_impl node(&ad, &s, sett, node_id(0), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id(0), ext, 0, cnt);
// DHT should be running on port 48199 now
bdecode_node response;
@ -1464,7 +1451,7 @@ int test_main()
g_sent_packets.clear();
do
{
dht::node_impl node(&ad, &s, sett, node_id::min(), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt);
udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234);
std::vector<udp::endpoint> nodesv;
@ -1536,7 +1523,7 @@ int test_main()
do
{
dht::node_id target = to_hash("1234876923549721020394873245098347598635");
dht::node_impl node(&ad, &s, sett, node_id::min(), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt);
udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234);
node.m_table.add_node(initial_node);
@ -1629,7 +1616,7 @@ int test_main()
g_sent_packets.clear();
do
{
dht::node_impl node(&ad, &s, sett, node_id::min(), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt);
udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234);
node.m_table.add_node(initial_node);
@ -1675,7 +1662,7 @@ int test_main()
g_sent_packets.clear();
do
{
dht::node_impl node(&ad, &s, sett, node_id::min(), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt);
udp::endpoint initial_node(address_v4::from_string("4.4.4.4"), 1234);
node.m_table.add_node(initial_node);
@ -1751,7 +1738,7 @@ int test_main()
g_sent_packets.clear();
do
{
dht::node_impl node(&ad, &s, sett, node_id::min(), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt);
enum { num_test_nodes = 2 };
node_entry nodes[num_test_nodes] =
{ node_entry(generate_next(), udp::endpoint(address_v4::from_string("4.4.4.4"), 1234))
@ -1833,7 +1820,7 @@ int test_main()
g_sent_packets.clear();
do
{
dht::node_impl node(&ad, &s, sett, node_id::min(), ext, 0, cnt);
dht::node_impl node(&s, sett, node_id::min(), ext, 0, cnt);
enum { num_test_nodes = 2 };
node_entry nodes[num_test_nodes] =
{ node_entry(generate_next(), udp::endpoint(address_v4::from_string("4.4.4.4"), 1234))

View File

@ -0,0 +1,290 @@
/*
Copyright (c) 2015, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
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
POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.hpp"
#include "libtorrent/heterogeneous_queue.hpp"
struct A
{
int a;
explicit A(int a_) : a(a_) {}
virtual int type() = 0;
virtual ~A() {}
};
struct B : A
{
int b;
explicit B(int a_, int b_) : A(a_), b(b_) {}
virtual int type() { return 1; }
};
struct C : A
{
char c[100];
explicit C(int a_, int c_) : A(a_)
{
memset(c, c_, sizeof(c));
}
virtual int type() { return 2; }
};
struct D
{
static int instances;
D() { ++instances; }
D(D const& d) { ++instances; }
~D() { --instances; }
};
struct E
{
E(char const* msg) : string_member(msg) {}
std::string string_member;
};
int D::instances = 0;
struct F
{
F(int f_)
: self(this)
, f(f_)
, constructed(true)
, destructed(false)
, gutted(false)
{}
F(F const& f_)
: self(this), f(f_.f)
, constructed(f_.constructed)
, destructed(f_.destructed)
, gutted(false)
{
TEST_EQUAL(f_.constructed, true);
TEST_EQUAL(f_.destructed, false);
TEST_EQUAL(f_.gutted, false);
}
#if __cplusplus >= 201103L
F(F&& f_)
: self(this)
, f(f_.f)
, constructed(f_.constructed)
, destructed(f_.destructed)
{
TEST_EQUAL(f_.constructed, true);
TEST_EQUAL(f_.destructed, false);
TEST_EQUAL(f_.gutted, false);
f_.gutted = true;
}
#endif
~F()
{
TEST_EQUAL(constructed, true);
TEST_EQUAL(destructed, false);
TEST_EQUAL(self, this);
destructed = true;
constructed = false;
}
void check_invariant()
{
TEST_EQUAL(constructed, true);
TEST_EQUAL(destructed, false);
TEST_EQUAL(gutted, false);
TEST_EQUAL(self, this);
}
F* self;
int f;
bool constructed;
bool destructed;
bool gutted;
private:
// non-copyable
F& operator=(F const& f);
};
int test_main()
{
using namespace libtorrent;
// test push_back of heterogeneous types
// and retrieval of their pointers
{
heterogeneous_queue<A> q;
q.push_back(B(0, 1));
TEST_EQUAL(q.size(), 1);
q.push_back(B(2, 3));
TEST_EQUAL(q.size(), 2);
q.push_back(B(4, 5));
TEST_EQUAL(q.size(), 3);
q.push_back(C(6, 7));
TEST_EQUAL(q.size(), 4);
q.push_back(C(8, 9));
TEST_EQUAL(q.size(), 5);
q.push_back(C(10, 11));
TEST_EQUAL(q.size(), 6);
std::vector<A*> ptrs;
q.get_pointers(ptrs);
TEST_EQUAL(ptrs.size(), q.size());
TEST_EQUAL(ptrs[0]->type(), 1);
TEST_EQUAL(ptrs[1]->type(), 1);
TEST_EQUAL(ptrs[2]->type(), 1);
TEST_EQUAL(ptrs[3]->type(), 2);
TEST_EQUAL(ptrs[4]->type(), 2);
TEST_EQUAL(ptrs[5]->type(), 2);
TEST_EQUAL(static_cast<B*>(ptrs[0])->a, 0);
TEST_EQUAL(static_cast<B*>(ptrs[0])->b, 1);
TEST_EQUAL(static_cast<B*>(ptrs[1])->a, 2);
TEST_EQUAL(static_cast<B*>(ptrs[1])->b, 3);
TEST_EQUAL(static_cast<B*>(ptrs[2])->a, 4);
TEST_EQUAL(static_cast<B*>(ptrs[2])->b, 5);
TEST_EQUAL(static_cast<C*>(ptrs[3])->a, 6);
TEST_EQUAL(static_cast<C*>(ptrs[3])->c[0], 7);
TEST_EQUAL(static_cast<C*>(ptrs[4])->a, 8);
TEST_EQUAL(static_cast<C*>(ptrs[4])->c[0], 9);
TEST_EQUAL(static_cast<C*>(ptrs[5])->a, 10);
TEST_EQUAL(static_cast<C*>(ptrs[5])->c[0], 11);
}
// test swap
{
heterogeneous_queue<A> q1;
heterogeneous_queue<A> q2;
q1.push_back(B(0, 1));
q1.push_back(B(2, 3));
q1.push_back(B(4, 5));
TEST_EQUAL(q1.size(), 3);
q2.push_back(C(6, 7));
q2.push_back(C(8, 9));
TEST_EQUAL(q2.size(), 2);
std::vector<A*> ptrs;
q1.get_pointers(ptrs);
TEST_EQUAL(ptrs.size(), q1.size());
TEST_EQUAL(ptrs[0]->type(), 1);
TEST_EQUAL(ptrs[1]->type(), 1);
TEST_EQUAL(ptrs[2]->type(), 1);
q2.get_pointers(ptrs);
TEST_EQUAL(ptrs.size(), q2.size());
TEST_EQUAL(ptrs[0]->type(), 2);
TEST_EQUAL(ptrs[1]->type(), 2);
q1.swap(q2);
q1.get_pointers(ptrs);
TEST_EQUAL(q1.size(), 2);
TEST_EQUAL(ptrs.size(), q1.size());
TEST_EQUAL(ptrs[0]->type(), 2);
TEST_EQUAL(ptrs[1]->type(), 2);
q2.get_pointers(ptrs);
TEST_EQUAL(q2.size(), 3);
TEST_EQUAL(ptrs.size(), q2.size());
TEST_EQUAL(ptrs[0]->type(), 1);
TEST_EQUAL(ptrs[1]->type(), 1);
TEST_EQUAL(ptrs[2]->type(), 1);
}
// test destruction
{
heterogeneous_queue<D> q;
TEST_EQUAL(D::instances, 0);
q.push_back(D());
TEST_EQUAL(D::instances, 1);
q.push_back(D());
TEST_EQUAL(D::instances, 2);
q.push_back(D());
TEST_EQUAL(D::instances, 3);
q.push_back(D());
TEST_EQUAL(D::instances, 4);
q.clear();
TEST_EQUAL(D::instances, 0);
}
// test copy/move
{
heterogeneous_queue<F> q;
// make sure the queue has to grow at some point, to exercise its
// copy/move of elements
for (int i = 0; i < 1000; ++i)
q.push_back(F(i));
std::vector<F*> ptrs;
q.get_pointers(ptrs);
TEST_EQUAL(ptrs.size(), 1000);
for (int i = 0; i < ptrs.size(); ++i)
{
ptrs[i]->check_invariant();
TEST_EQUAL(ptrs[i]->f, i);
}
// destroy all objects, asserting that their invariant still holds
q.clear();
}
{
heterogeneous_queue<E> q;
for (int i = 0; i < 10000; ++i)
{
q.push_back(E("testing to allocate non-trivial objects"));
}
}
return 0;
}

View File

@ -57,7 +57,7 @@ int peer_disconnects = 0;
int tracker_responses = 0;
bool on_alert(alert* a)
bool on_alert(alert const* a)
{
if (alert_cast<tracker_reply_alert>(a))
++tracker_responses;
@ -259,28 +259,34 @@ void test_transfer(settings_pack const& sett)
std::vector<char> resume_data;
alert const* a = ses2.wait_for_alert(seconds(10));
time_point start = clock_type::now();
while (a)
while (true)
{
std::auto_ptr<alert> holder = ses2.pop_alert();
std::cerr << "ses2: " << a->message() << std::endl;
if (alert_cast<save_resume_data_alert>(a))
std::vector<alert*> alerts;
ses2.pop_alerts(&alerts);
if (alerts.empty()) break;
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
bencode(std::back_inserter(resume_data)
alert* a = *i;
std::cerr << "ses2: " << a->message() << std::endl;
if (alert_cast<save_resume_data_alert>(a))
{
bencode(std::back_inserter(resume_data)
, *alert_cast<save_resume_data_alert>(a)->resume_data);
fprintf(stderr, "saved resume data\n");
break;
}
else if (alert_cast<save_resume_data_failed_alert>(a))
{
fprintf(stderr, "save resume failed\n");
break;
}
if (total_seconds(clock_type::now() - start) > 10)
break;
fprintf(stderr, "saved resume data\n");
break;
}
else if (alert_cast<save_resume_data_failed_alert>(a))
{
fprintf(stderr, "save resume failed\n");
break;
}
if (total_seconds(clock_type::now() - start) > 10)
break;
a = ses2.wait_for_alert(seconds(10));
ses2.wait_for_alert(seconds(10));
}
}
TEST_CHECK(resume_data.size());

View File

@ -56,9 +56,9 @@ char const* proxy_name[] = {
std::vector<std::string> rejected_trackers;
bool alert_predicate(libtorrent::alert* a)
bool alert_predicate(libtorrent::alert const* a)
{
anonymous_mode_alert* am = alert_cast<anonymous_mode_alert>(a);
anonymous_mode_alert const* am = alert_cast<anonymous_mode_alert>(a);
if (am == NULL) return false;
if (am->kind == anonymous_mode_alert::tracker_not_anonymous)

View File

@ -101,8 +101,8 @@ void test_read_piece(int flags)
TEST_CHECK(!ec);
TEST_CHECK(tor1.is_valid());
std::auto_ptr<alert> a = wait_for_alert(ses, torrent_finished_alert::alert_type, "ses");
TEST_CHECK(a.get());
alert const* a = wait_for_alert(ses, torrent_finished_alert::alert_type, "ses");
TEST_CHECK(a);
TEST_CHECK(tor1.status().is_seeding);
@ -117,10 +117,10 @@ void test_read_piece(int flags)
a = wait_for_alert(ses, read_piece_alert::alert_type, "ses");
TEST_CHECK(a.get());
if (a.get())
TEST_CHECK(a);
if (a)
{
read_piece_alert* rp = alert_cast<read_piece_alert>(a.get());
read_piece_alert const* rp = alert_cast<read_piece_alert>(a);
TEST_CHECK(rp);
if (rp)
{

View File

@ -51,7 +51,7 @@ boost::shared_ptr<T> clone_ptr(boost::shared_ptr<T> const& ptr)
int peer_disconnects = 0;
bool on_alert(alert* a)
bool on_alert(alert const* a)
{
if (alert_cast<peer_disconnected_alert>(a))
++peer_disconnects;
@ -138,8 +138,8 @@ void test_remap_files_gather(storage_mode_t storage_mode = storage_mode_sparse)
for (int i = 0; i < 50; ++i)
{
print_alerts(ses1, "ses1", true, true, true, on_alert);
print_alerts(ses2, "ses2", true, true, true, on_alert);
print_alerts(ses1, "ses1", true, true, true, &on_alert);
print_alerts(ses2, "ses2", true, true, true, &on_alert);
torrent_status st1 = tor1.status();
torrent_status st2 = tor2.status();
@ -181,7 +181,7 @@ void test_remap_files_gather(storage_mode_t storage_mode = storage_mode_sparse)
for (int i = 0; i < 50; ++i)
{
print_alerts(ses2, "ses2", true, true, true, on_alert);
print_alerts(ses2, "ses2", true, true, true, &on_alert);
torrent_status st2 = tor2.status();
@ -273,8 +273,8 @@ void test_remap_files_scatter(storage_mode_t storage_mode = storage_mode_sparse)
for (int i = 0; i < 50; ++i)
{
print_alerts(ses1, "ses1", true, true, true, on_alert);
print_alerts(ses2, "ses2", true, true, true, on_alert);
print_alerts(ses1, "ses1", true, true, true, &on_alert);
print_alerts(ses2, "ses2", true, true, true, &on_alert);
torrent_status st1 = tor1.status();
torrent_status st2 = tor2.status();
@ -316,7 +316,7 @@ void test_remap_files_scatter(storage_mode_t storage_mode = storage_mode_sparse)
for (int i = 0; i < 50; ++i)
{
print_alerts(ses2, "ses2", true, true, true, on_alert);
print_alerts(ses2, "ses2", true, true, true, &on_alert);
torrent_status st2 = tor2.status();
@ -440,8 +440,8 @@ void test_remap_files_prio(storage_mode_t storage_mode = storage_mode_sparse)
for (int i = 0; i < 50; ++i)
{
print_alerts(ses1, "ses1", true, true, true, on_alert);
print_alerts(ses2, "ses2", true, true, true, on_alert);
print_alerts(ses1, "ses1", true, true, true, &on_alert);
print_alerts(ses2, "ses2", true, true, true, &on_alert);
torrent_status st1 = tor1.status();
torrent_status st2 = tor2.status();

View File

@ -55,20 +55,20 @@ int test_main()
// we're allowing a larger queue than we have cache.
std::auto_ptr<alert> a;
alert const* a;
for (;;)
{
a = wait_for_alert(ses, performance_alert::alert_type, "ses1");
if (a.get() == NULL) break;
TEST_EQUAL(a.get()->type(), performance_alert::alert_type);
if (a == NULL) break;
TEST_EQUAL(a->type(), performance_alert::alert_type);
if (alert_cast<performance_alert>(a.get())->warning_code
if (alert_cast<performance_alert>(a)->warning_code
== performance_alert::too_high_disk_queue_limit)
break;
}
TEST_CHECK(a.get());
TEST_CHECK(a);
sett.set_int(settings_pack::unchoke_slots_limit, 0);
ses.apply_settings(sett);

View File

@ -204,7 +204,7 @@ void run_storage_tests(boost::shared_ptr<torrent_info> info
{ // avoid having two storages use the same files
file_pool fp;
libtorrent::asio::io_service ios;
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop), NULL);
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop));
storage_params p;
p.path = test_path;
p.files = &fs;
@ -296,7 +296,7 @@ void test_remove(std::string const& test_path, bool unbuffered)
std::vector<char> buf;
file_pool fp;
io_service ios;
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop), NULL);
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop));
aux::session_settings set;
set.set_int(settings_pack::disk_io_write_mode
@ -369,7 +369,7 @@ void test_rename(std::string const& test_path)
std::vector<char> buf;
file_pool fp;
io_service ios;
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop), NULL);
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop));
aux::session_settings set;
boost::shared_ptr<default_storage> s = setup_torrent(fs, fp, buf, test_path
@ -446,8 +446,8 @@ void test_check_files(std::string const& test_path
file_pool fp;
libtorrent::asio::io_service ios;
counters cnt;
disk_io_thread io(ios, NULL, cnt, NULL);
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop), NULL);
disk_io_thread io(ios, cnt, NULL);
disk_buffer_pool dp(16 * 1024, ios, boost::bind(&nop));
storage_params p;
p.files = &fs;
p.path = test_path;
@ -653,11 +653,12 @@ void test_fastresume(std::string const& test_path)
return;
h.save_resume_data();
std::auto_ptr<alert> ra = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(ra.get());
if (ra.get()) resume = *alert_cast<save_resume_data_alert>(ra.get())->resume_data;
alert const* ra = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(ra);
if (ra) resume = *alert_cast<save_resume_data_alert>(ra)->resume_data;
ses.remove_torrent(h, lt::session::delete_files);
std::auto_ptr<alert> da = wait_for_alert(ses, torrent_deleted_alert::alert_type);
alert const* da = wait_for_alert(ses, torrent_deleted_alert::alert_type);
TEST_CHECK(da);
}
TEST_CHECK(!exists(combine_path(test_path, combine_path("tmp1", "temporary"))));
if (exists(combine_path(test_path, combine_path("tmp1", "temporary"))))
@ -679,23 +680,10 @@ void test_fastresume(std::string const& test_path)
bencode(std::back_inserter(p.resume_data), resume);
torrent_handle h = ses.add_torrent(p, ec);
std::auto_ptr<alert> a = ses.pop_alert();
time_point end = clock_type::now() + seconds(20);
while (clock_type::now() < end
&& (a.get() == 0
|| alert_cast<fastresume_rejected_alert>(a.get()) == 0))
{
if (ses.wait_for_alert(end - clock_type::now()) == 0)
{
std::cerr << "wait_for_alert() expired" << std::endl;
break;
}
a = ses.pop_alert();
assert(a.get());
std::cerr << a->message() << std::endl;
}
alert const* a = wait_for_alert(ses, fastresume_rejected_alert::alert_type
, "ses");
// we expect the fast resume to be rejected because the files were removed
TEST_CHECK(alert_cast<fastresume_rejected_alert>(a.get()) != 0);
TEST_CHECK(alert_cast<fastresume_rejected_alert>(a) != 0);
}
remove_all(combine_path(test_path, "tmp1"), ec);
if (ec && ec != boost::system::errc::no_such_file_or_directory)
@ -703,7 +691,7 @@ void test_fastresume(std::string const& test_path)
<< "': " << ec.message() << std::endl;
}
bool got_file_rename_alert(alert* a)
bool got_file_rename_alert(alert const* a)
{
return alert_cast<libtorrent::file_renamed_alert>(a)
|| alert_cast<libtorrent::file_rename_failed_alert>(a);
@ -752,9 +740,9 @@ void test_rename_file_in_fastresume(std::string const& test_path)
TEST_CHECK(s.state == torrent_status::seeding);
h.save_resume_data();
std::auto_ptr<alert> ra = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(ra.get());
if (ra.get()) resume = *alert_cast<save_resume_data_alert>(ra.get())->resume_data;
alert const* ra = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(ra);
if (ra) resume = *alert_cast<save_resume_data_alert>(ra)->resume_data;
ses.remove_torrent(h);
}
TEST_CHECK(!exists(combine_path(test_path, "tmp2/temporary")));
@ -789,9 +777,9 @@ void test_rename_file_in_fastresume(std::string const& test_path)
TEST_CHECK(stat.state == torrent_status::seeding);
h.save_resume_data();
std::auto_ptr<alert> ra = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(ra.get());
if (ra.get()) resume = *alert_cast<save_resume_data_alert>(ra.get())->resume_data;
alert const* ra = wait_for_alert(ses, save_resume_data_alert::alert_type);
TEST_CHECK(ra);
if (ra) resume = *alert_cast<save_resume_data_alert>(ra)->resume_data;
ses.remove_torrent(h);
}
TEST_CHECK(resume.dict().find("mapped_files") != resume.dict().end());

View File

@ -137,27 +137,18 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
std::cout << "reading piece 0" << std::endl;
h.read_piece(0);
alert const* a = ses.wait_for_alert(seconds(10));
bool passed = false;
while (a)
alert const* a = wait_for_alert(ses, read_piece_alert::alert_type, "read_piece");
TEST_CHECK(a);
read_piece_alert const* rpa = alert_cast<read_piece_alert>(a);
TEST_CHECK(rpa);
if (rpa)
{
std::auto_ptr<alert> al = ses.pop_alert();
assert(al.get());
std::cout << " " << al->message() << std::endl;
if (read_piece_alert* rpa = alert_cast<read_piece_alert>(al.get()))
{
std::cout << "SUCCEEDED!" << std::endl;
passed = true;
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), piece.size()) == 0);
TEST_CHECK(rpa->size == info->piece_size(0));
TEST_CHECK(rpa->piece == 0);
TEST_CHECK(hasher(&piece[0], piece.size()).final() == info->hash_for_piece(0));
break;
}
a = ses.wait_for_alert(seconds(10));
TEST_CHECK(a);
std::cout << "SUCCEEDED!" << std::endl;
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), piece.size()) == 0);
TEST_CHECK(rpa->size == info->piece_size(0));
TEST_CHECK(rpa->piece == 0);
TEST_CHECK(hasher(&piece[0], piece.size()).final() == info->hash_for_piece(0));
}
TEST_CHECK(passed);
}
}

View File

@ -57,7 +57,7 @@ int peer_disconnects = 0;
int tracker_responses = 0;
bool on_alert(alert* a)
bool on_alert(alert const* a)
{
if (alert_cast<tracker_reply_alert>(a))
++tracker_responses;

View File

@ -56,7 +56,7 @@ namespace lt = libtorrent;
int peer_disconnects = 0;
bool on_alert(alert* a)
bool on_alert(alert const* a)
{
if (alert_cast<peer_disconnected_alert>(a))
++peer_disconnects;

View File

@ -73,17 +73,17 @@ void usage()
exit(1);
}
std::auto_ptr<alert> wait_for_alert(lt::session& s, int alert_type)
alert* wait_for_alert(lt::session& s, int alert_type)
{
std::auto_ptr<alert> ret;
alert* ret = NULL;
bool found = false;
while (!found)
{
s.wait_for_alert(seconds(5));
std::deque<alert*> alerts;
std::vector<alert*> alerts;
s.pop_alerts(&alerts);
for (std::deque<alert*>::iterator i = alerts.begin()
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
if ((*i)->type() != alert_type)
@ -94,10 +94,9 @@ std::auto_ptr<alert> wait_for_alert(lt::session& s, int alert_type)
fflush(stdout);
spinner = (spinner + 1) & 3;
//print some alerts?
delete *i;
continue;
}
ret = std::auto_ptr<alert>(*i);
ret = *i;
found = true;
}
}
@ -214,9 +213,9 @@ int main(int argc, char* argv[])
printf("GET %s\n", to_hex(target.to_string()).c_str());
std::auto_ptr<alert> a = wait_for_alert(s, dht_immutable_item_alert::alert_type);
alert* a = wait_for_alert(s, dht_immutable_item_alert::alert_type);
dht_immutable_item_alert* item = alert_cast<dht_immutable_item_alert>(a.get());
dht_immutable_item_alert* item = alert_cast<dht_immutable_item_alert>(a);
entry data;
if (item)
data.swap(item->item);
@ -298,9 +297,9 @@ int main(int argc, char* argv[])
bootstrap(s);
s.dht_get_item(public_key);
std::auto_ptr<alert> a = wait_for_alert(s, dht_mutable_item_alert::alert_type);
alert* a = wait_for_alert(s, dht_mutable_item_alert::alert_type);
dht_mutable_item_alert* item = alert_cast<dht_mutable_item_alert>(a.get());
dht_mutable_item_alert* item = alert_cast<dht_mutable_item_alert>(a);
entry data;
if (item)
data.swap(item->item);

View File

@ -34,6 +34,7 @@ set +e
mkdir test-coverage
set -e
run_test test_heterogeneous_queue "include/libtorrent/heterogeneous_queue.hpp"
run_test test_dht "*/kademlia/*"
run_test test_bdecode "*/bdecode.*"
run_test test_piece_picker "*/piece_picker.*"