mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-12 13:12:32 +00:00
* 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:
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user