added an asynchronous save_resume_data to make it easier to synchronize with the disk IO thread

This commit is contained in:
Arvid Norberg
2008-04-13 18:54:36 +00:00
parent 6639f72804
commit 3fea2080fd
12 changed files with 657 additions and 438 deletions

View File

@@ -596,16 +596,10 @@ void scan_dir(path const& dir_path
}
h.pause();
if (h.has_metadata())
{
entry data = h.write_resume_data();
std::stringstream s;
s << h.get_torrent_info().name() << ".fastresume";
boost::filesystem::ofstream out(h.save_path() / s.str(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), data);
}
ses.remove_torrent(h);
// the alert handler for save_resume_data_alert
// will save it to disk and remove the torrent
h.save_resume_data();
handles.erase(i++);
}
}
@@ -988,21 +982,49 @@ int main(int ac, char* av[])
{
if (c == 'q')
{
// keep track of the number of resume data
// alerts to wait for
int num_resume_data = 0;
for (handles_t::iterator i = handles.begin();
i != handles.end(); ++i)
{
torrent_handle& h = i->second;
if (!h.is_valid() || !h.has_metadata()) continue;
// pause
std::cout << "pausing " << h.name() << std::endl;
h.pause();
// save_resume_data will generate an alert when it's done
h.save_resume_data();
++num_resume_data;
}
std::cout << "waiting for resume data" << std::endl;
entry data = h.write_resume_data();
std::stringstream s;
s << h.get_torrent_info().name() << ".fastresume";
boost::filesystem::ofstream out(h.save_path() / s.str(), std::ios_base::binary);
while (num_resume_data > 0)
{
alert const* a = ses.wait_for_alert(seconds(10));
if (a == 0)
{
std::cout << " aborting with " << num_resume_data << " outstanding "
"torrents to save resume data for" << std::endl;
break;
}
std::auto_ptr<alert> holder = ses.pop_alert();
save_resume_data_alert const* rd = dynamic_cast<save_resume_data_alert const*>(a);
if (rd == 0)
{
std::cout << a->msg() << std::endl;
continue;
}
torrent_handle h = rd->handle;
boost::filesystem::ofstream out(h.save_path()
/ (h.get_torrent_info().name() + ".fastresume"), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), data);
ses.remove_torrent(h);
bencode(std::ostream_iterator<char>(out), *rd->resume_data);
std::cout << "fast resume data saved for " << h.name() << std::endl;
--num_resume_data;
}
break;
}
@@ -1085,15 +1107,9 @@ int main(int ac, char* av[])
// write resume data for the finished torrent
torrent_handle h = p->handle;
entry data = h.write_resume_data();
std::stringstream s;
s << h.get_torrent_info().name() << ".fastresume";
boost::filesystem::ofstream out(h.save_path() / s.str(), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), data);
h.save_resume_data();
event_string << p->handle.get_torrent_info().name() << ": "
<< a->msg();
event_string << h.name() << ": " << a->msg();
}
else if (peer_error_alert* p = dynamic_cast<peer_error_alert*>(a.get()))
{
@@ -1119,6 +1135,18 @@ int main(int ac, char* av[])
{
event_string << "(" << p->ip << ") " << p->msg();
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get()))
{
torrent_handle h = p->handle;
if (p->resume_data)
{
boost::filesystem::ofstream out(h.save_path() / (h.name() + ".fastresume"), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), *p->resume_data);
if (h.is_paused()) ses.remove_torrent(h);
}
event_string << "(" << h.name() << ") " << p->msg();
}
else if (torrent_alert* p = dynamic_cast<torrent_alert*>(a.get()))
{
std::string name;
@@ -1356,6 +1384,7 @@ int main(int ac, char* av[])
}
}
std::cout << "saving session state" << std::endl;
{
entry session_state = ses.state();
boost::filesystem::ofstream out(".ses_state"
@@ -1365,12 +1394,14 @@ int main(int ac, char* av[])
}
#ifndef TORRENT_DISABLE_DHT
std::cout << "saving DHT state" << std::endl;
dht_state = ses.dht_state();
boost::filesystem::ofstream out(".dht_state"
, std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), dht_state);
#endif
std::cout << "closing session" << std::endl;
}
catch (std::exception& e)
{