diff --git a/docs/manual.rst b/docs/manual.rst index 4a404ef9f..b247f0d1b 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -3057,7 +3057,7 @@ closing down. Example code to pause and save resume data for all torrents and wait for the alerts:: - int num_resume_data = 0; + extern int outstanding_resume_data; // global counter of outstanding resume data std::vector handles = ses.get_torrents(); ses.pause(); for (std::vector::iterator i = handles.begin(); @@ -3067,12 +3067,13 @@ Example code to pause and save resume data for all torrents and wait for the ale if (!h.is_valid()) continue; torrent_status s = h.status(); if (!s.has_metadata) continue; + if (!s.need_save_resume_data()) continue; h.save_resume_data(); - ++num_resume_data; + ++outstanding_resume_data; } - while (num_resume_data > 0) + while (outstanding_resume_data > 0) { alert const* a = ses.wait_for_alert(seconds(10)); @@ -3084,7 +3085,7 @@ Example code to pause and save resume data for all torrents and wait for the ale if (alert_cast(a)) { process_alert(a); - --num_resume_data; + --outstanding_resume_data; continue; } @@ -3100,8 +3101,15 @@ Example code to pause and save resume data for all torrents and wait for the ale / (h.get_torrent_info().name() + ".fastresume"), std::ios_base::binary); out.unsetf(std::ios_base::skipws); bencode(std::ostream_iterator(out), *rd->resume_data); - --num_resume_data; + --outstanding_resume_data; } + +.. note:: Note how ``outstanding_resume_data`` is a global counter in this example. + This is deliberate, otherwise there is a race condition for torrents that + was just asked to save their resume data, they posted the alert, but it has + not been received yet. Those torrents would report that they don't need to + save resume data again, and skipped by the initial loop, and thwart the counter + otherwise. need_save_resume_data() @@ -3116,6 +3124,11 @@ torrent was first loaded or since the last time the resume data was saved. When saving resume data periodically, it makes sense to skip any torrent which hasn't downloaded anything since the last time. +.. note:: A torrent's resume data is considered saved as soon as the alert + is posted. It is important to make sure this alert is received and handled + in order for this function to be meaningful. + + status() -------- diff --git a/src/alert.cpp b/src/alert.cpp index 5370fa805..a5260b8dd 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -341,6 +341,10 @@ namespace libtorrent { { while (!m_alerts.empty()) { + TORRENT_ASSERT(alert_cast(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(); }