* Reworked how hashing is queued, state must 1 and removed the

set_hash_failed hacks when closing, etc.

* Changed the attributes of blocks in transfer view.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@727 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2006-06-21 22:14:10 +00:00
parent d2fc993514
commit 70eacfe738
10 changed files with 75 additions and 95 deletions
+1 -1
View File
@@ -208,7 +208,7 @@ DownloadFactory::receive_success() {
} else {
// Use the state thingie here, move below.
if (m_start)
m_manager->download_list()->start(download);
m_manager->download_list()->start_normal(download);
m_manager->download_store()->save(download);
}
+47 -56
View File
@@ -160,19 +160,17 @@ DownloadList::erase(iterator itr) {
return base_type::erase(itr);
}
// void
// DownloadList::save(Download* d) {
// }
void
bool
DownloadList::open(Download* download) {
try {
open_throw(download);
return true;
} catch (torrent::local_error& e) {
control->core()->push_log(e.what());
return false;
}
}
@@ -203,14 +201,15 @@ void
DownloadList::close_throw(Download* download) {
check_contains(download);
// When pause gets called it will clear the initial hash check state
// and set hash failed. This should ensure hashing doesn't restart
// until resume gets called.
pause(download);
// Check for is_open after pause due to hashing.
if (!download->is_open())
return;
// When pause gets called it will clear the initial hash checking.
if (download->is_active())
pause(download);
// Save the torrent on close, this covers shutdown and if a torrent
// is manually closed which would clear the progress data. For
// better crash protection, save regulary in addition to this.
@@ -220,39 +219,35 @@ DownloadList::close_throw(Download* download) {
// Reconsider this save. Should be done explicitly when shutting down.
//control->core()->download_store()->save(download);
// FIXME: Urgh, need to do something sane when closing a download
// that has been queued for hashing. ATM just close the torrent and
// call the hash_removed slots. This might open and restart the
// hashing of this torrent.
// if (download->is_hash_checking()) {
// download->download()->close();
// // Hash removed slot must be called after close as we can't atm
// // stop already started hash checks except through close.
// std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
// } else {
// download->download()->close();
// }
// But this isn't correct either, i think... ATM do the borking
// thing, the hash queue won't be updated. Need to properly handle
// erasing a download.
// Propably should do its own thingie in erase rather than calling
// close.
download->download()->close();
if (!download->is_hash_failed() &&
download->variable()->get_value("state") != 0 &&
download->variable()->get_value("hashing") != Download::variable_hashing_stopped)
throw torrent::client_error("DownloadList::close_throw(...) called but we're going into a hashing loop.");
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
std::for_each(slot_map_close().begin(), slot_map_close().end(), download_list_call(download));
}
void
DownloadList::start(Download* download) {
DownloadList::start_normal(Download* download) {
check_contains(download);
// Clear hash failed as we're doing a manual start and want to try
// hashing again.
download->set_hash_failed(false);
download->variable()->set("state", (int64_t)1);
resume(download);
}
void
DownloadList::start_try(Download* download) {
check_contains(download);
// Don't clear the hash failed as this function is used by scripts,
// etc.
download->variable()->set("state", (int64_t)1);
resume(download);
@@ -282,21 +277,20 @@ DownloadList::resume(Download* download) {
// It is also assumed the is_hash_checked flag gets cleared when
// 'hashing' was set.
if (!download->is_hash_checked()) {
download->set_hash_failed(false);
// Set 'hashing' to started if hashing wasn't started, else keep
// the old value.
if (download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
// If the hash failed flag wasn't cleared then hashing won't be
// initiated. The check here is just for convenience so the hash
// queue doesn't need to check it.
if (!download->is_hash_failed() && download->variable()->get_value("hashing") == Download::variable_hashing_stopped)
download->variable()->set("hashing", Download::variable_hashing_initial);
std::for_each(slot_map_hash_queued().begin(), slot_map_hash_queued().end(), download_list_call(download));
return;
}
download->variable()->set("state_changed", cachedTime.seconds());
open_throw(download);
download->variable()->set("state_changed", cachedTime.seconds());
if (download->is_done()) {
download->set_connection_type(download->variable()->get_string("connection_seed"));
} else {
@@ -327,13 +321,10 @@ DownloadList::pause(Download* download) {
try {
// Don't stop if we're doing the final hashing.
if (download->variable()->get_value("hashing") == Download::variable_hashing_initial) {
// Clear initial hashing, but retain the other types.
if (download->variable()->get_value("hashing") == Download::variable_hashing_initial)
download->variable()->set("hashing", Download::variable_hashing_stopped);
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
}
if (!download->download()->is_active())
return;
@@ -341,6 +332,7 @@ DownloadList::pause(Download* download) {
download->download()->hash_resume_save();
std::for_each(slot_map_stop().begin(), slot_map_stop().end(), download_list_call(download));
std::for_each(slot_map_hash_removed().begin(), slot_map_hash_removed().end(), download_list_call(download));
download->variable()->set("state_changed", cachedTime.seconds());
@@ -359,8 +351,10 @@ DownloadList::check_hash(Download* download) {
try {
download->variable()->set("hashing", Download::variable_hashing_rehash);
hash_clear(download);
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped)
return;
hash_queue(download, Download::variable_hashing_rehash);
} catch (torrent::local_error& e) {
control->core()->push_log(e.what());
@@ -438,12 +432,11 @@ DownloadList::hash_done(Download* download) {
}
void
DownloadList::hash_clear(Download* download) {
DownloadList::hash_queue(Download* download, int type) {
check_contains(download);
// Set hash failed so close_throw won't cause the hash queue to
// reopen this download.
download->set_hash_failed(true);
if (download->variable()->get_value("hashing") != Download::variable_hashing_stopped)
throw torrent::client_error("DownloadList::hash_queue(...) hashing already queued.");
close_throw(download);
download->download()->hash_resume_clear();
@@ -465,9 +458,7 @@ DownloadList::received_finished(Download* download) {
if (control->variable()->get_value("check_hash")) {
// Set some 'checking_finished_thingie' variable to make hash_done
// trigger correctly, also so it can bork on missing data.
download->variable()->set("hashing", Download::variable_hashing_last);
hash_clear(download);
hash_queue(download, Download::variable_hashing_last);
} else {
confirm_finished(download);
+4 -4
View File
@@ -86,16 +86,16 @@ public:
//void save(Download* d);
void open(Download* d);
bool open(Download* d);
void open_throw(Download* d);
void close(Download* d);
void close_throw(Download* d);
void start(Download* d);
void start_normal(Download* d);
void start_try(Download* d);
void stop(Download* d);
// These do not change the rtorrent:state.
void resume(Download* d);
void pause(Download* d);
@@ -169,7 +169,7 @@ public:
private:
void hash_done(Download* d);
void hash_clear(Download* d);
void hash_queue(Download* d, int type);
inline void check_contains(Download* d);
+2 -2
View File
@@ -385,8 +385,8 @@ Manager::receive_hashing_changed() {
try {
if ((*itr)->is_hash_checked())
throw torrent::client_error("core::Manager::receive_hashing_changed() hash already checked.");
if ((*itr)->is_hash_checked() || (*itr)->is_hash_checking())
throw torrent::client_error("core::Manager::receive_hashing_changed() hash already checked or checking.");
if ((*itr)->is_hash_failed())
continue;
+1 -1
View File
@@ -97,7 +97,7 @@ Scheduler::update() {
throw torrent::client_error("Scheduler::update() loop bork.");
if (!(*itr)->is_active()) {
m_downloadList->resume(*itr);
m_downloadList->start_try(*itr);
++curActive;
}
}
+6 -8
View File
@@ -53,8 +53,7 @@ View::~View() {
if (m_name.empty())
return;
std::for_each(m_list->slot_map_begin(), m_list->slot_map_end(),
rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
std::for_each(m_list->slot_map_begin(), m_list->slot_map_end(), rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
}
void
@@ -115,9 +114,9 @@ struct view_downloads_compare : std::binary_function<Download*, Download*, bool>
bool operator () (Download* d1, Download* d2) const {
for (View::sort_list::const_iterator itr = m_sort.begin(), last = m_sort.end(); itr != last; ++itr)
if ((**itr)(d1, d2))
return true;
return true;
else if ((**itr)(d2, d1))
return false;
return false;
// Since we're testing equivalence, return false if we're
// equal. This is a requirement for the stl sorting algorithms.
@@ -133,7 +132,7 @@ struct view_downloads_filter : std::unary_function<Download*, bool> {
bool operator () (Download* d1) const {
for (View::filter_list::const_iterator itr = m_filter.begin(), last = m_filter.end(); itr != last; ++itr)
if (!(**itr)(d1))
return false;
return false;
// The default filter action is to return true, to not filter the
// download out.
@@ -176,8 +175,7 @@ void
View::clear_filter_on() {
// Don't clear insert and erase as these are required to keep the
// View up-to-date with the available downloads.
std::for_each(m_list->slot_map_begin() + DownloadList::SLOTS_OPEN, m_list->slot_map_end(),
rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
std::for_each(m_list->slot_map_begin() + DownloadList::SLOTS_OPEN, m_list->slot_map_end(), rak::bind2nd(std::ptr_fun(&DownloadList::erase_key), "0_view_" + m_name));
}
inline void
@@ -239,7 +237,7 @@ View::received(core::Download* download, int event) {
} else {
if (itr >= begin_filtered())
return;
return;
erase(itr);
base_type::push_back(download);
+10 -20
View File
@@ -81,34 +81,24 @@ WindowDownloadTransferList::redraw() {
char id;
chtype attr = A_NORMAL;
if (bItr->transfers()->size() >= 1) {
if (bItr->is_finished()) {
attr = A_REVERSE;
id = key_id(bItr->leader()->const_peer_info());
if (bItr->leader() != NULL) {
attr = A_REVERSE;
id = key_id(bItr->leader()->const_peer_info());
} else {
attr = A_REVERSE | A_UNDERLINE;
id = key_id(bItr->transfers()->back()->const_peer_info());
}
if (bItr->transfers()->size() > 1)
attr = A_BOLD;
} else if (bItr->is_transfering()) {
attr = A_BOLD;
id = key_id(bItr->leader()->const_peer_info());
} else if (bItr->queued()->size() >= 1) {
id = key_id(bItr->queued()->back()->const_peer_info());
if (bItr->queued()->size() > 1)
attr = A_BOLD;
} else if (bItr->is_finished()) {
// Temporary until we fix the code so transfers are kept
// around.
id = '*';
id = std::tolower(key_id(bItr->queued()->back()->const_peer_info()));
} else {
id = '.';
}
if (bItr->size_all() > 1)
attr |= A_UNDERLINE;
m_canvas->print_char(attr | id);
}
}
+2 -1
View File
@@ -196,8 +196,9 @@ main(int argc, char** argv) {
control->variable()->process_command("view_sort_new = incomplete,state_changed");
control->variable()->process_command("view_sort_current = incomplete,state_changed_reverse");
// The hashing view does not include stopped torrents.
control->variable()->process_command("view_add = hashing");
control->variable()->process_command("view_filter = hashing,hashing");
control->variable()->process_command("view_filter = hashing,hashing,started");
control->variable()->process_command("view_filter_on = hashing,hash_queued,hash_removed,hash_done");
control->variable()->process_command("view_sort_new = hashing,state_changed");
control->variable()->process_command("view_sort_current = hashing,state_changed");
+1 -1
View File
@@ -129,7 +129,7 @@ apply_start_tied(Control* m, const std::string& arg) {
rak::equal(*itr, rak::bind2nd(std::mem_fun(&core::Download::variable_string), "tied_to_file")));
if (dItr != m->core()->download_list()->end())
m->core()->download_list()->start(*dItr);
m->core()->download_list()->start_try(*dItr);
}
}
+1 -1
View File
@@ -200,7 +200,7 @@ DownloadList::receive_start_download() {
if (m_view->focus() == m_view->end_visible())
return;
m_control->core()->download_list()->start(*m_view->focus());
m_control->core()->download_list()->start_normal(*m_view->focus());
m_view->set_last_changed();
}