diff --git a/include/libtorrent/alert.hpp b/include/libtorrent/alert.hpp index 904028a39..f36338c21 100644 --- a/include/libtorrent/alert.hpp +++ b/include/libtorrent/alert.hpp @@ -130,12 +130,15 @@ namespace libtorrent { 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_dispatch_function(boost::function const&); + private: std::queue m_alerts; mutable boost::mutex m_mutex; boost::condition m_condition; int m_alert_mask; size_t m_queue_size_limit; + boost::function m_dispatch; }; struct TORRENT_EXPORT unhandled_alert : std::exception diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index e44fcb899..d1495c959 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -216,6 +216,7 @@ namespace libtorrent void set_alert_mask(int m); size_t set_alert_queue_size_limit(size_t queue_size_limit_); std::auto_ptr pop_alert(); + void set_alert_dispatch(boost::function const&); alert const* wait_for_alert(time_duration max_wait); diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index acd887e05..a14c10efb 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -378,6 +378,7 @@ namespace libtorrent size_t set_alert_queue_size_limit(size_t queue_size_limit_); alert const* wait_for_alert(time_duration max_wait); + void set_alert_dispatch(boost::function const& fun); connection_queue& get_connection_queue(); diff --git a/src/alert.cpp b/src/alert.cpp index 14c5c4e5c..08373e1cd 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -80,10 +80,31 @@ namespace libtorrent { return m_alerts.front(); } + void alert_manager::set_dispatch_function(boost::function const& fun) + { + boost::mutex::scoped_lock lock(m_mutex); + + m_dispatch = fun; + + while (!m_alerts.empty()) + { + m_dispatch(*m_alerts.front()); + delete m_alerts.front(); + m_alerts.pop(); + } + } + void alert_manager::post_alert(const alert& alert_) { boost::mutex::scoped_lock lock(m_mutex); + if (m_dispatch) + { + TORRENT_ASSERT(m_alerts.empty()); + m_dispatch(alert_); + return; + } + if (m_alerts.size() >= m_queue_size_limit) return; m_alerts.push(alert_.clone().release()); m_condition.notify_all(); diff --git a/src/session.cpp b/src/session.cpp index 22f8f0364..06b19f6eb 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -565,6 +565,11 @@ namespace libtorrent return m_impl->pop_alert(); } + void session::set_alert_dispatch(boost::function const& fun) + { + return m_impl->set_alert_dispatch(fun); + } + alert const* session::wait_for_alert(time_duration max_wait) { return m_impl->wait_for_alert(max_wait); diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 04cb197e1..4b471c0c6 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -2425,6 +2425,12 @@ namespace aux { m_bandwidth_manager[peer_connection::upload_channel]->throttle(bytes_per_second); } + void session_impl::set_alert_dispatch(boost::function const& fun) + { + mutex_t::scoped_lock l(m_mutex); + m_alerts.set_dispatch_function(fun); + } + std::auto_ptr session_impl::pop_alert() { mutex_t::scoped_lock l(m_mutex); diff --git a/test/test_transfer.cpp b/test/test_transfer.cpp index 72e85f761..84c0feb49 100644 --- a/test/test_transfer.cpp +++ b/test/test_transfer.cpp @@ -101,6 +101,11 @@ void test_rate() } +void print_alert(alert const& a) +{ + std::cout << "ses1 (alert dispatch function): " << a.message() << std::endl; +} + void test_transfer() { session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48075, 49000)); @@ -134,6 +139,7 @@ void test_transfer() ses1.set_alert_mask(alert::all_categories & ~alert::progress_notification); ses2.set_alert_mask(alert::all_categories & ~alert::progress_notification); + ses1.set_alert_dispatch(&print_alert); for (int i = 0; i < 30; ++i) {