made alerts move-only and remove dispatch function and other deprecated alert functions requiring alert to be copyable (#721)

This commit is contained in:
Arvid Norberg 2016-05-13 08:19:44 -04:00
parent 84f70a77ee
commit 167cbe74b5
14 changed files with 51 additions and 322 deletions

View File

@ -1,3 +1,4 @@
* made alerts move-only
* move files one-by-one when moving storage for a torrent
* removed RSS support
* removed feature to resolve country for peers

View File

@ -267,17 +267,9 @@ namespace boost
void bind_alert()
{
using boost::noncopyable;
#ifndef TORRENT_NO_DEPRECATE
typedef boost::shared_ptr<alert> alert_holder;
#if BOOST_VERSION >= 106000
register_ptr_to_python<boost::shared_ptr<alert> >();
#endif
#else
typedef alert alert_holder;
#endif
{
scope alert_scope = class_<alert, alert_holder, noncopyable >("alert", no_init)
scope alert_scope = class_<alert, noncopyable >("alert", no_init)
.def("message", &alert::message)
.def("what", &alert::what)
.def("category", &alert::category)

View File

@ -314,21 +314,12 @@ namespace
}
#endif // TORRENT_NO_DEPRECATE
#ifndef TORRENT_NO_DEPRECATE
boost::shared_ptr<alert>
#else
alert const*
#endif
wait_for_alert(lt::session& s, int ms)
{
allow_threading_guard guard;
alert const* a = s.wait_for_alert(milliseconds(ms));
#ifndef TORRENT_NO_DEPRECATE
if (a == NULL) return boost::shared_ptr<alert>();
return boost::shared_ptr<alert>(a->clone().release());
#else
return a;
#endif
}
list get_torrents(lt::session& s)
@ -409,35 +400,6 @@ namespace
return e;
}
#ifndef TORRENT_NO_DEPRECATE
object pop_alert(lt::session& ses)
{
std::auto_ptr<alert> a;
{
allow_threading_guard guard;
a = ses.pop_alert();
}
return object(boost::shared_ptr<alert>(a.release()));
}
list pop_alerts(lt::session& ses)
{
std::vector<alert*> alerts;
{
allow_threading_guard guard;
ses.pop_alerts(&alerts);
}
list ret;
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
ret.append(boost::shared_ptr<alert>((*i)->clone().release()));
}
return ret;
}
#else
list pop_alerts(lt::session& ses)
{
std::vector<alert*> alerts;
@ -454,7 +416,6 @@ namespace
}
return ret;
}
#endif
void load_state(lt::session& ses, entry const& st, boost::uint32_t flags)
{
@ -792,14 +753,10 @@ void bind_session()
.def("load_state", &load_state, (arg("entry"), arg("flags") = 0xffffffff))
.def("save_state", &save_state, (arg("entry"), arg("flags") = 0xffffffff))
.def("pop_alerts", &pop_alerts)
.def("wait_for_alert", &wait_for_alert
#ifdef TORRENT_NO_DEPRECATE
, return_internal_reference<>()
#endif
.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))

View File

@ -87,6 +87,10 @@ namespace libtorrent {
{
public:
alert(alert const& rhs) = delete;
alert& operator=(alert const&) = delete;
alert(alert&& rhs) = default;
#ifndef TORRENT_NO_DEPRECATE
// only here for backwards compatibility
enum severity_t { debug, info, warning, critical, fatal, none };
@ -269,33 +273,17 @@ namespace libtorrent {
TORRENT_DEPRECATED
severity_t severity() const { return warning; }
// returns a pointer to a copy of the alert.
TORRENT_DEPRECATED
std::auto_ptr<alert> clone() const { return clone_impl(); }
protected:
virtual bool discardable_impl() const { return true; }
virtual std::auto_ptr<alert> clone_impl() const = 0;
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif // TORRENT_NO_DEPRECATE
protected:
// the alert is not copyable (but for backwards compatibility reasons it
// retains the ability to clone itself, for now).
#if __cplusplus >= 201103L
alert(alert const& rhs) = default;
#endif
private:
// explicitly disallow assignment and copyconstruction
alert& operator=(alert const&);
time_point m_timestamp;
};
@ -303,15 +291,15 @@ namespace libtorrent {
// more specific alert type, in order to query it for more information.
template <class T> T* alert_cast(alert* a)
{
if (a == 0) return 0;
if (a == nullptr) return nullptr;
if (a->type() == T::alert_type) return static_cast<T*>(a);
return 0;
return nullptr;
}
template <class T> T const* alert_cast(alert const* a)
{
if (a == 0) return 0;
if (a == nullptr) return nullptr;
if (a->type() == T::alert_type) return static_cast<T const*>(a);
return 0;
return nullptr;
}
} // namespace libtorrent

View File

@ -76,14 +76,7 @@ namespace libtorrent {
void emplace_alert(Args&&... args)
{
std::unique_lock<std::mutex> 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
@ -131,10 +124,6 @@ namespace libtorrent {
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
#ifndef TORRENT_DISABLE_EXTENSIONS
void add_extension(boost::shared_ptr<plugin> ext);
#endif
@ -152,11 +141,6 @@ namespace libtorrent {
boost::uint32_t m_alert_mask;
int 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()).

View File

@ -83,6 +83,7 @@ namespace libtorrent
{
// internal
torrent_alert(aux::stack_allocator& alloc, torrent_handle const& h);
torrent_alert(torrent_alert&&) = default;
// internal
static const int alert_type = 0;
@ -101,7 +102,7 @@ namespace libtorrent
#endif
protected:
aux::stack_allocator const& m_alloc;
std::reference_wrapper<aux::stack_allocator const> m_alloc;
private:
int m_name_idx;
};
@ -113,6 +114,7 @@ namespace libtorrent
// internal
peer_alert(aux::stack_allocator& alloc, torrent_handle const& h,
tcp::endpoint const& i, peer_id const& pi);
peer_alert(peer_alert&&) = default;
static const int alert_type = 1;
static const int static_category = alert::peer_notification;
@ -151,37 +153,11 @@ namespace libtorrent
int m_url_idx;
};
#ifndef TORRENT_NO_DEPRECATE
#define TORRENT_CLONE(name) \
virtual std::auto_ptr<alert> clone_impl() const override \
{ return std::auto_ptr<alert>(new name(*this)); }
#else
#define TORRENT_CLONE(name)
#endif
// we can only use = default in C++11
// the purpose of this is just to make all alert types non-copyable from user
// code. The heterogeneous queue does not yet have an emplace_back(), so it
// still needs to copy alerts, but the important part is that it's not
// copyable for clients.
// TODO: Once the backwards compatibility of clone() is removed, and once
// C++11 is required, this can be simplified to just say = delete
#if __cplusplus >= 201103L
#define TORRENT_PROTECTED_CCTOR(name) \
protected: \
template <class T> friend struct heterogeneous_queue; \
name(name const&) = default; \
public:
#else
#define TORRENT_PROTECTED_CCTOR(name)
#endif
#define TORRENT_DEFINE_ALERT_IMPL(name, seq, prio) \
TORRENT_PROTECTED_CCTOR(name) \
name(name&&) = default; \
static const int priority = prio; \
static const int alert_type = seq; \
virtual int type() const override { return alert_type; } \
TORRENT_CLONE(name) \
virtual int category() const override { return static_category; } \
virtual char const* what() const override { return #name; }
@ -1313,7 +1289,7 @@ namespace libtorrent
tcp::endpoint endpoint;
private:
aux::stack_allocator const& m_alloc;
std::reference_wrapper<aux::stack_allocator const> m_alloc;
int m_interface_idx;
};
@ -1437,7 +1413,7 @@ namespace libtorrent
private:
// TODO: 2 should the alert baseclass have this object instead?
aux::stack_allocator const& m_alloc;
std::reference_wrapper<aux::stack_allocator const> m_alloc;
int m_log_idx;
};
@ -2068,7 +2044,7 @@ namespace libtorrent
char const* msg() const;
private:
aux::stack_allocator const& m_alloc;
std::reference_wrapper<aux::stack_allocator const> m_alloc;
int m_str_idx;
};
@ -2277,7 +2253,7 @@ namespace libtorrent
dht_module_t module;
private:
aux::stack_allocator& m_alloc;
std::reference_wrapper<aux::stack_allocator const> m_alloc;
int m_msg_idx;
};
@ -2312,7 +2288,7 @@ namespace libtorrent
udp::endpoint node;
private:
aux::stack_allocator& m_alloc;
std::reference_wrapper<aux::stack_allocator> m_alloc;
int m_msg_idx;
int m_size;
};
@ -2339,7 +2315,7 @@ namespace libtorrent
std::vector<tcp::endpoint> peers() const;
private:
aux::stack_allocator& m_alloc;
std::reference_wrapper<aux::stack_allocator> m_alloc;
int m_num_peers;
int m_peers_idx;
};
@ -2366,7 +2342,7 @@ namespace libtorrent
bdecode_node response() const;
private:
aux::stack_allocator& m_alloc;
std::reference_wrapper<aux::stack_allocator> m_alloc;
int m_response_idx;
int m_response_size;
};
@ -2432,7 +2408,6 @@ namespace libtorrent
#undef TORRENT_DEFINE_ALERT_IMPL
#undef TORRENT_DEFINE_ALERT
#undef TORRENT_DEFINE_ALERT_PRIO
#undef TORRENT_CLONE
enum { num_alert_types = 90 }; // this enum represents "max_alert_index" + 1
}

View File

@ -442,7 +442,6 @@ namespace libtorrent
#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;

View File

@ -199,13 +199,9 @@ namespace libtorrent {
template <class U>
static void move(uintptr_t* dst, uintptr_t* src)
{
U* rhs = reinterpret_cast<U*>(src);
#if __cplusplus >= 201103L
new (dst) U(std::move(*rhs));
#else
new (dst) U(*rhs);
#endif
rhs->~U();
U& rhs = *reinterpret_cast<U*>(src);
new (dst) U(static_cast<U&&>(rhs));
rhs.~U();
}
uintptr_t* m_storage;

View File

@ -887,18 +887,6 @@ namespace libtorrent
TORRENT_DEPRECATED
void pop_alerts(std::deque<alert*>* alerts);
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
TORRENT_DEPRECATED
std::auto_ptr<alert> pop_alert();
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif
// Alerts is the main mechanism for libtorrent to report errors and
@ -976,27 +964,6 @@ namespace libtorrent
TORRENT_DEPRECATED
boost::uint32_t get_alert_mask() const;
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#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 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.
TORRENT_DEPRECATED
void set_alert_dispatch(
boost::function<void(std::auto_ptr<alert>)> const& fun);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
// 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

@ -90,7 +90,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return name.c_str();
#else
return m_alloc.ptr(m_name_idx);
return m_alloc.get().ptr(m_name_idx);
#endif
}
@ -131,7 +131,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return url.c_str();
#else
return m_alloc.ptr(m_url_idx);
return m_alloc.get().ptr(m_url_idx);
#endif
}
@ -206,7 +206,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return name.c_str();
#else
return m_alloc.ptr(m_name_idx);
return m_alloc.get().ptr(m_name_idx);
#endif
}
@ -307,7 +307,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return msg.c_str();
#else
return m_alloc.ptr(m_msg_idx);
return m_alloc.get().ptr(m_msg_idx);
#endif
}
@ -339,7 +339,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return msg.c_str();
#else
return m_alloc.ptr(m_msg_idx);
return m_alloc.get().ptr(m_msg_idx);
#endif
}
@ -402,7 +402,7 @@ namespace libtorrent {
return msg.c_str();
#else
if (m_msg_idx == -1) return "";
else return m_alloc.ptr(m_msg_idx);
else return m_alloc.get().ptr(m_msg_idx);
#endif
}
@ -676,7 +676,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return path.c_str();
#else
return m_alloc.ptr(m_path_idx);
return m_alloc.get().ptr(m_path_idx);
#endif
}
@ -700,7 +700,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return file.c_str();
#else
return m_alloc.ptr(m_file_idx);
return m_alloc.get().ptr(m_file_idx);
#endif
}
@ -839,7 +839,7 @@ namespace libtorrent {
char const* listen_failed_alert::listen_interface() const
{
return m_alloc.ptr(m_interface_idx);
return m_alloc.get().ptr(m_interface_idx);
}
std::string listen_failed_alert::message() const
@ -970,7 +970,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return msg.c_str();
#else
return m_alloc.ptr(m_log_idx);
return m_alloc.get().ptr(m_log_idx);
#endif
}
@ -1015,7 +1015,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return file.c_str();
#else
return m_alloc.ptr(m_path_idx);
return m_alloc.get().ptr(m_path_idx);
#endif
}
@ -1184,7 +1184,7 @@ namespace libtorrent {
#ifndef TORRENT_NO_DEPRECATE
return trackerid.c_str();
#else
return m_alloc.ptr(m_tracker_idx);
return m_alloc.get().ptr(m_tracker_idx);
#endif
}
@ -1222,7 +1222,7 @@ namespace libtorrent {
char const* torrent_error_alert::filename() const
{
return m_alloc.ptr(m_file_idx);
return m_alloc.get().ptr(m_file_idx);
}
torrent_added_alert::torrent_added_alert(aux::stack_allocator& alloc
@ -1585,7 +1585,7 @@ namespace libtorrent {
char const* log_alert::msg() const
{
return m_alloc.ptr(m_str_idx);
return m_alloc.get().ptr(m_str_idx);
}
std::string log_alert::message() const
@ -1601,7 +1601,7 @@ namespace libtorrent {
char const* torrent_log_alert::msg() const
{
return m_alloc.ptr(m_str_idx);
return m_alloc.get().ptr(m_str_idx);
}
std::string torrent_log_alert::message() const
@ -1624,7 +1624,7 @@ namespace libtorrent {
char const* peer_log_alert::msg() const
{
return m_alloc.ptr(m_str_idx);
return m_alloc.get().ptr(m_str_idx);
}
std::string peer_log_alert::message() const
@ -1719,7 +1719,7 @@ namespace libtorrent {
char const* url_seed_alert::server_url() const
{
return m_alloc.ptr(m_url_idx);
return m_alloc.get().ptr(m_url_idx);
}
char const* url_seed_alert::error_message() const
@ -1728,7 +1728,7 @@ namespace libtorrent {
return msg.c_str();
#else
if (m_msg_idx == -1) return "";
return m_alloc.ptr(m_msg_idx);
return m_alloc.get().ptr(m_msg_idx);
#endif
}
@ -1752,7 +1752,7 @@ namespace libtorrent {
char const* file_error_alert::filename() const
{
return m_alloc.ptr(m_file_idx);
return m_alloc.get().ptr(m_file_idx);
}
std::string file_error_alert::message() const
@ -1786,7 +1786,7 @@ namespace libtorrent {
char const* dht_log_alert::log_message() const
{
return m_alloc.ptr(m_msg_idx);
return m_alloc.get().ptr(m_msg_idx);
}
std::string dht_log_alert::message() const
@ -1817,7 +1817,7 @@ namespace libtorrent {
char const* dht_pkt_alert::pkt_buf() const
{
return m_alloc.ptr(m_msg_idx);
return m_alloc.get().ptr(m_msg_idx);
}
int dht_pkt_alert::pkt_size() const
@ -1893,7 +1893,7 @@ namespace libtorrent {
std::vector<tcp::endpoint> dht_get_peers_reply_alert::peers() const {
std::vector<tcp::endpoint> peers(m_num_peers);
const char *ptr = m_alloc.ptr(m_peers_idx);
const char *ptr = m_alloc.get().ptr(m_peers_idx);
for (int i = 0; i < m_num_peers; i++) {
std::size_t size = detail::read_uint8(ptr);
memcpy(peers[i].data(), ptr, size);
@ -1924,14 +1924,14 @@ namespace libtorrent {
char msg[1050];
snprintf(msg, sizeof(msg), "DHT direct response (address=%s) [ %s ]"
, addr.address().to_string().c_str()
, m_response_size ? std::string(m_alloc.ptr(m_response_idx), m_response_size).c_str() : "");
, m_response_size ? std::string(m_alloc.get().ptr(m_response_idx), m_response_size).c_str() : "");
return msg;
}
bdecode_node dht_direct_response_alert::response() const
{
if (m_response_size == 0) return bdecode_node();
char const* start = m_alloc.ptr(m_response_idx);
char const* start = m_alloc.get().ptr(m_response_idx);
char const* end = start + m_response_size;
error_code ec;
bdecode_node ret;
@ -1959,7 +1959,7 @@ namespace libtorrent {
std::vector<piece_block> ret;
ret.resize(m_num_blocks);
char const* start = m_alloc.ptr(m_array_idx);
char const* start = m_alloc.get().ptr(m_array_idx);
memcpy(&ret[0], start, m_num_blocks * sizeof(piece_block));
return ret;

View File

@ -93,50 +93,6 @@ namespace libtorrent
#endif
}
#ifndef TORRENT_NO_DEPRECATE
bool alert_manager::maybe_dispatch(alert const& a)
{
if (m_dispatch)
{
m_dispatch(a.clone());
return true;
}
return false;
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
void alert_manager::set_dispatch_function(
boost::function<void(std::auto_ptr<alert>)> const& fun)
{
std::unique_lock<std::mutex> lock(m_mutex);
m_dispatch = fun;
heterogeneous_queue<alert> storage;
m_alerts[m_generation].swap(storage);
lock.unlock();
std::vector<alert*> alerts;
storage.get_pointers(alerts);
for (std::vector<alert*>::iterator i = alerts.begin()
, end(alerts.end()); i != end; ++i)
{
m_dispatch((*i)->clone());
}
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif
void alert_manager::set_notify_function(boost::function<void()> const& fun)
{
std::unique_lock<std::mutex> lock(m_mutex);

View File

@ -1009,26 +1009,6 @@ namespace libtorrent
return TORRENT_SYNC_CALL_RET(int, max_connections);
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
std::auto_ptr<alert> session_handle::pop_alert()
{
alert const* a = m_impl->pop_alert();
if (a == NULL) return std::auto_ptr<alert>();
return a->clone();
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
void session_handle::pop_alerts(std::deque<alert*>* alerts)
{
m_impl->pop_alerts(alerts);
}
#endif // TORRENT_NO_DEPRECATE
// the alerts are const, they may not be deleted by the client
@ -1086,20 +1066,6 @@ namespace libtorrent
return get_settings().get_int(settings_pack::alert_mask);
}
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
void session_handle::set_alert_dispatch(boost::function<void(std::auto_ptr<alert>)> const& fun)
{
m_impl->alerts().set_dispatch_function(fun);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
void session_handle::start_lsd()
{
settings_pack p;

View File

@ -6417,25 +6417,6 @@ namespace aux {
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 = int(m_alert_pointers.size());
}
#endif
alert* session_impl::wait_for_alert(time_duration max_wait)

View File

@ -103,39 +103,6 @@ TORRENT_TEST(priority_limit)
TEST_EQUAL(alerts.size(), 200);
}
void test_dispatch_fun(int& cnt, std::auto_ptr<alert> const& a)
{
++cnt;
}
TORRENT_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;