diff --git a/bindings/python/src/torrent_handle.cpp b/bindings/python/src/torrent_handle.cpp index 6aec7a05e..1efbcc5d6 100644 --- a/bindings/python/src/torrent_handle.cpp +++ b/bindings/python/src/torrent_handle.cpp @@ -334,7 +334,7 @@ void bind_torrent_handle() .def("prioritize_files", &prioritize_files) .def("file_priorities", &file_priorities) .def("use_interface", &torrent_handle::use_interface) - .def("save_resume_data", _(&torrent_handle::save_resume_data)) + .def("save_resume_data", _(&torrent_handle::save_resume_data), arg("flags" = 0)) .def("need_save_resume_data", _(&torrent_handle::need_save_resume_data)) .def("force_reannounce", _(force_reannounce0)) .def("force_reannounce", &force_reannounce) @@ -366,6 +366,10 @@ void bind_torrent_handle() #endif ; + enum_("save_resume_flags_t") + .value("flush_disk_cache", torrent_handle::flush_disk_cache) + ; + enum_("deadline_flags") .value("alert_when_available", torrent_handle::alert_when_available) ; diff --git a/docs/manual.rst b/docs/manual.rst index 6c058d71d..d73b937cc 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -1905,7 +1905,7 @@ Its declaration looks like this:: std::string name() const; - void save_resume_data() const; + void save_resume_data(int flags = 0) const; bool need_save_resume_data() const; void force_reannounce() const; void force_dht_announce() const; @@ -2715,11 +2715,15 @@ save_resume_data() :: - void save_resume_data() const; + void save_resume_data(int flags = 0) const; ``save_resume_data()`` generates fast-resume data and returns it as an entry_. This entry_ is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_. +The ``flags`` argument may be set to ``torrent_handle::flush_cache``. Doing so will flush the disk +cache before creating the resume data. This avoids a problem with file timestamps in the resume +data in case the cache hasn't been flushed yet. + This operation is asynchronous, ``save_resume_data`` will return immediately. The resume data is delivered when it's done through an `save_resume_data_alert`_. @@ -2739,6 +2743,12 @@ the `save_resume_data_alert`_ though. There's no need to pause when saving inter .. warning:: If you pause every torrent individually instead of pausing the session, every torrent will have its paused state saved in the resume data! +.. warning:: The resume data contains the modification timestamps for all files. If one file has + been modified when the torrent is added again, the will be rechecked. When shutting down, make + sure to flush the disk cache before saving the resume data. This will make sure that the file + timestamps are up to date and won't be modified after saving the resume data. The recommended way + to do this is to pause the torrent, which will flush the cache and disconnect all peers. + .. note:: It is typically a good idea to save resume data whenever a torrent is completed or paused. In those cases you don't need to pause the torrent or the session, since the torrent will do no more writing to its files. If you save resume data for torrents when they are paused, you can accelerate the diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index b9d2cc17e..2d91d4e9b 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -238,7 +238,8 @@ namespace libtorrent bool is_torrent_paused() const { return !m_allow_peers; } void force_recheck(); void save_resume_data(); - bool need_save_resume_data() const + + bool need_save_resume_data(int flags = 0) const { // save resume data every 15 minutes regardless, just to // keep stats up to date diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 5b9e69c0c..56a6a761f 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -476,7 +476,9 @@ namespace libtorrent void flush_cache() const; void force_recheck() const; - void save_resume_data() const; + + enum save_resume_flags_t { flush_disk_cache = 1 }; + void save_resume_data(int flags) const; bool need_save_resume_data() const; bool is_auto_managed() const; diff --git a/src/torrent.cpp b/src/torrent.cpp index af9ef5ed9..4607066e4 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -5479,7 +5479,7 @@ namespace libtorrent } // this is an async operation triggered by the client - void torrent::save_resume_data() + void torrent::save_resume_data(int flags) { TORRENT_ASSERT(m_ses.is_network_thread()); INVARIANT_CHECK; @@ -5505,6 +5505,10 @@ namespace libtorrent , get_handle())); return; } + + if (flags & torrent_handle::flush_disk_cache) + m_storage->async_release_files(); + m_storage->async_save_resume_data( boost::bind(&torrent::on_save_resume_data, shared_from_this(), _1, _2)); }