* Added "working_directory" option that calls chdir.

* Added "session_on_completion" option which saves the session torrent
when a download finishes.

* Handle SIGTERM gracefully, saving session torrents etc.

* Implemented session directory lockfile, use "session_lock" option to
disable.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@629 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2006-02-01 12:11:09 +00:00
parent 6f44f8f920
commit d06ecda46a
21 changed files with 283 additions and 178 deletions
+3 -3
View File
@@ -99,7 +99,7 @@ DownloadFactory::receive_load() {
if (std::strncmp(m_uri.c_str(), "http://", 7) == 0) {
// Http handling here.
m_stream = new std::stringstream;
HttpQueue::iterator itr = m_manager->get_http_queue().insert(m_uri, m_stream);
HttpQueue::iterator itr = m_manager->http_queue().insert(m_uri, m_stream);
(*itr)->signal_done().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_loaded));
(*itr)->signal_failed().slots().push_front(sigc::mem_fun(*this, &DownloadFactory::receive_failed));
@@ -139,7 +139,7 @@ DownloadFactory::receive_success() {
Manager::DListItr itr = m_manager->insert(m_stream, m_printLog);
if (itr == m_manager->get_download_list().end()) {
if (itr == m_manager->download_list().end()) {
// core::Manager should already have added the error message to
// the log.
m_slotFinished();
@@ -206,7 +206,7 @@ DownloadFactory::receive_success() {
if (m_start)
m_manager->start(*itr, m_printLog);
m_manager->get_download_store().save(*itr);
m_manager->download_store().save(*itr);
}
m_slotFinished();
+35 -7
View File
@@ -52,16 +52,44 @@
namespace core {
void
DownloadStore::use(const std::string& path) {
m_path = path;
DownloadStore::enable(bool lock) {
if (is_enabled())
throw torrent::input_error("Session directory already enabled.");
if (!m_path.empty() && *m_path.rbegin() != '/')
m_path += '/';
if (m_path.empty())
return;
if (lock)
m_lockfile.set_path(m_path + "rtorrent.lock");
else
m_lockfile.set_path(std::string());
if (!m_lockfile.try_lock())
throw torrent::input_error("Could not lock session directory: \"" + m_path + "\".");
}
void
DownloadStore::disable() {
if (!is_enabled())
return;
m_lockfile.unlock();
}
void
DownloadStore::set_path(const std::string& path) {
if (is_enabled())
throw torrent::input_error("Tried to change session directory while it is enabled.");
if (!path.empty() && *path.rbegin() != '/')
m_path = path + '/';
else
m_path = path;
}
void
DownloadStore::save(Download* d) {
if (!is_active())
if (!is_enabled())
return;
std::fstream f((create_filename(d) + ".new").c_str(), std::ios::out | std::ios::trunc);
@@ -92,7 +120,7 @@ DownloadStore::save(Download* d) {
void
DownloadStore::remove(Download* d) {
if (!is_active())
if (!is_enabled())
return;
::unlink(create_filename(d).c_str());
@@ -100,7 +128,7 @@ DownloadStore::remove(Download* d) {
utils::Directory
DownloadStore::get_formated_entries() {
if (!is_active())
if (!is_enabled())
return utils::Directory();
utils::Directory d(m_path);
+14 -9
View File
@@ -40,6 +40,7 @@
#include <string>
#include "utils/directory.h"
#include "utils/lockfile.h"
namespace core {
@@ -48,22 +49,26 @@ class Download;
class DownloadStore {
public:
// Disable by passing an empty string.
void use(const std::string& path);
bool is_enabled() { return m_lockfile.is_locked(); }
bool is_active() { return !m_path.empty(); }
void enable(bool lock);
void disable();
void save(Download* d);
void remove(Download* d);
const std::string& path() const { return m_path; }
void set_path(const std::string& path);
void save(Download* d);
void remove(Download* d);
// Currently shows all entries in the correct format.
utils::Directory get_formated_entries();
utils::Directory get_formated_entries();
private:
static bool is_correct_format(std::string f);
std::string create_filename(Download* d);
static bool is_correct_format(std::string f);
std::string create_filename(Download* d);
std::string m_path;
std::string m_path;
utils::Lockfile m_lockfile;
};
}
+6 -5
View File
@@ -107,6 +107,7 @@ Manager::initialize_first() {
torrent::initialize(m_pollManager->get_torrent_poll());
}
// Most of this should be possible to move out.
void
Manager::initialize_second() {
torrent::Http::set_factory(m_pollManager->get_http_stack()->get_http_factory());
@@ -116,11 +117,8 @@ Manager::initialize_second() {
// Register slots to be called when a download is inserted/erased,
// opened or closed.
// m_downloadList.slot_map_insert()["0_initialize_bencode"] = sigc::mem_fun(*this, &Manager::initialize_bencode);
m_downloadList.slot_map_insert()["1_connect_network_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_network_log), sigc::mem_fun(m_logComplete, &Log::push_front));
// m_downloadList.slot_map_insert()["1_connect_tracker_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_tracker_log), sigc::mem_fun(m_logComplete, &Log::push_front));
m_downloadList.slot_map_insert()["1_connect_storage_log"] = sigc::bind(sigc::ptr_fun(&connect_signal_storage_log), sigc::mem_fun(m_logComplete, &Log::push_front));
//m_downloadList.slot_map_insert()["1_enable_udp_trackers"] = sigc::bind(sigc::mem_fun(&core::Download::enable_udp_trackers), true);
m_downloadList.slot_map_erase()["1_hash_queue_remove"] = sigc::mem_fun(m_hashQueue, &HashQueue::remove);
m_downloadList.slot_map_erase()["1_store_remove"] = sigc::mem_fun(m_downloadStore, &DownloadStore::remove);
@@ -319,9 +317,12 @@ Manager::receive_download_done_hash_checked(Download* d) {
if (!d->get_download().is_active())
m_downloadList.start(d);
if (control->variables()->get_string("session_on_completion") == "yes")
m_downloadStore.save(d);
// Don't send if we did a hash check and found incompelete chunks.
//if (d->is_done())
d->get_download().tracker_send_completed();
if (d->is_done())
d->get_download().tracker_send_completed();
}
void
+4 -4
View File
@@ -60,10 +60,10 @@ public:
Manager();
DownloadList& get_download_list() { return m_downloadList; }
DownloadStore& get_download_store() { return m_downloadStore; }
HashQueue& get_hash_queue() { return m_hashQueue; }
HttpQueue& get_http_queue() { return m_httpQueue; }
DownloadList& download_list() { return m_downloadList; }
DownloadStore& download_store() { return m_downloadStore; }
HashQueue& hash_queue() { return m_hashQueue; }
HttpQueue& http_queue() { return m_httpQueue; }
PollManager* get_poll_manager() { return m_pollManager; }
Log& get_log_important() { return m_logImportant; }