diff --git a/docs/manual.rst b/docs/manual.rst index decc77a04..b99a54104 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -82,6 +82,10 @@ The ``session`` class has the following synopsis:: torrent_handle add_torrent(add_torrent_params const& params); + void pause(); + void resume(); + bool is_paused() const; + session_proxy abort(); enum options_t @@ -194,10 +198,23 @@ returns. So, it's advised that any kind of interface (such as windows) are close destructing the session object. Because it can take a few second for it to finish. The timeout can be set with ``set_settings()``. +pause() resume() is_paused() +---------------------------- + + :: + void pause(); + void resume(); + bool is_paused() const; + +Pausing the session has the same effect as pausing every torrent in it. Resuming +will restore the torrents to their previous paused state. i.e. the session pause +state is separate from the torrent pause state. A torrent is inactive if it is +paused or if the session is paused. + abort() ------- -:: + :: session_proxy abort(); diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 13f7b9e51..2d1b43619 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -982,6 +982,12 @@ int main(int ac, char* av[]) } } + if (c == ' ') + { + if (ses.is_paused()) ses.resume(); + else ses.pause(); + } + if (c == 'm') { std::cout << "saving peers for torrents" << std::endl; @@ -1198,7 +1204,7 @@ int main(int ac, char* av[]) std::stringstream out; out << "[q] quit [i] toggle peers [d] toggle downloading pieces [p] toggle paused " "[a] toggle piece bar [s] toggle download sequential [f] toggle files " - "[j] force recheck\n" + "[j] force recheck [space] toggle session pause\n" "[1] toggle IP [2] toggle AS [3] toggle timers [4] toggle block progress " "[5] toggle peer rate [6] toggle failures [7] toggle send buffers\n"; diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index 22ed68d49..fa4f0d276 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -189,6 +189,10 @@ namespace libtorrent , int nat_transport); bool is_aborted() const { return m_abort; } + bool is_paused() const { return m_paused; } + + void pause(); + void resume(); void set_ip_filter(ip_filter const& f); void set_port_filter(port_filter const& f); @@ -454,6 +458,9 @@ namespace libtorrent // should exit volatile bool m_abort; + // is true if the session is paused + bool m_paused; + // the max number of unchoked peers as set by the user int m_max_uploads; diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index fcae0be32..7c8075d4f 100644 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -212,6 +212,10 @@ namespace libtorrent session_proxy abort() { return session_proxy(m_impl); } + void pause(); + void resume(); + bool is_paused() const; + session_status status() const; cache_status get_cache_status() const; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index c0ddb798a..971a4f1bc 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -195,7 +195,12 @@ namespace libtorrent bool has_error() const { return !m_error.empty(); } void pause(); void resume(); - bool is_paused() const { return m_paused; } + + void do_pause(); + void do_resume(); + + bool is_paused() const; + bool is_torrent_paused() const { return m_paused; } void force_recheck(); void save_resume_data(); diff --git a/src/session.cpp b/src/session.cpp index bfceb7024..b9e5f3c4c 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -324,6 +324,10 @@ namespace libtorrent return m_impl->status(); } + void session::pause() { m_impl->pause(); } + void session::resume() { m_impl->resume(); } + bool session::is_paused() const { return m_impl->is_paused(); } + void session::get_cache_info(sha1_hash const& ih , std::vector& ret) const { diff --git a/src/session_impl.cpp b/src/session_impl.cpp index af16b06b4..c98d99182 100644 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -158,6 +158,7 @@ namespace aux { , m_listen_port_retries(listen_port_range.second - listen_port_range.first) , m_listen_interface(address::from_string(listen_interface), listen_port_range.first) , m_abort(false) + , m_paused(false) , m_max_uploads(8) , m_allowed_upload_slots(8) , m_max_connections(200) @@ -389,6 +390,32 @@ namespace aux { } #endif + void session_impl::pause() + { + mutex_t::scoped_lock l(m_mutex); + if (m_paused) return; + m_paused = true; + for (torrent_map::iterator i = m_torrents.begin() + , end(m_torrents.end()); i != end; ++i) + { + torrent& t = *i->second; + if (!t.is_torrent_paused()) t.do_pause(); + } + } + + void session_impl::resume() + { + mutex_t::scoped_lock l(m_mutex); + if (!m_paused) return; + m_paused = false; + for (torrent_map::iterator i = m_torrents.begin() + , end(m_torrents.end()); i != end; ++i) + { + torrent& t = *i->second; + t.do_resume(); + } + } + void session_impl::abort() { mutex_t::scoped_lock l(m_mutex); diff --git a/src/torrent.cpp b/src/torrent.cpp index cb9a74175..67bd9f558 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -761,8 +761,7 @@ namespace libtorrent bind(&torrent::on_announce_disp, self, _1)); // announce with the local discovery service - if (!m_paused) - m_ses.announce_lsd(m_torrent_file->info_hash()); + if (!is_paused()) m_ses.announce_lsd(m_torrent_file->info_hash()); } else { @@ -772,7 +771,7 @@ namespace libtorrent } #ifndef TORRENT_DISABLE_DHT - if (m_paused) return; + if (is_paused()) return; if (!m_ses.m_dht) return; ptime now = time_now(); if (should_announce_dht() && now - m_last_dht_announce > minutes(14)) @@ -842,7 +841,7 @@ namespace libtorrent m_just_paused = false; return true; } - return !m_paused && m_next_request < time_now(); + return !is_paused() && m_next_request < time_now(); } void torrent::tracker_warning(tracker_request const& req, std::string const& msg) @@ -1501,7 +1500,7 @@ namespace libtorrent m_abort = true; // if the torrent is paused, it doesn't need // to announce with even=stopped again. - if (!m_paused) + if (!is_paused()) m_event = tracker_request::stopped; // disconnect all peers and close all // files belonging to the torrents @@ -2865,7 +2864,7 @@ namespace libtorrent bool torrent::want_more_peers() const { return int(m_connections.size()) < m_max_connections - && !m_paused + && !is_paused() && m_state != torrent_status::checking_files && (m_state != torrent_status::queued_for_checking || !valid_metadata()) @@ -3596,7 +3595,7 @@ namespace libtorrent #endif disconnect_all(); - if (!m_paused) + if (!is_paused()) m_just_paused = true; m_paused = true; // tell the tracker that we stopped @@ -3711,11 +3710,24 @@ namespace libtorrent } } + bool torrent::is_paused() const + { + return m_paused || m_ses.is_paused(); + } + void torrent::pause() { INVARIANT_CHECK; if (m_paused) return; + m_paused = true; + if (m_ses.is_paused()) return; + do_pause(); + } + + void torrent::do_pause() + { + if (!is_paused()) return; #ifndef TORRENT_DISABLE_EXTENSIONS for (extension_list_t::iterator i = m_extensions.begin() @@ -3740,7 +3752,6 @@ namespace libtorrent #endif disconnect_all(); - m_paused = true; // tell the tracker that we stopped m_event = tracker_request::stopped; m_just_paused = true; @@ -3766,6 +3777,13 @@ namespace libtorrent INVARIANT_CHECK; if (!m_paused) return; + m_paused = false; + do_resume(); + } + + void torrent::do_resume() + { + if (is_paused()) return; #ifndef TORRENT_DISABLE_EXTENSIONS for (extension_list_t::iterator i = m_extensions.begin() @@ -3781,7 +3799,6 @@ namespace libtorrent } #endif - m_paused = false; m_started = time_now(); m_error.clear();