* Added slot map's for insert/erase, open/close, start/stop and

finished downloads in DownloadList, moved stuff from core::Manager to
the slot maps.

* Added check hash key ^r, though triggering check hash on finished
signals currently borks.

* Made tracker dump into an option.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@470 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2005-06-20 19:14:41 +00:00
parent 9a3d75490f
commit 7e77635353
16 changed files with 243 additions and 151 deletions
+2
View File
@@ -47,6 +47,8 @@ public:
void open() { m_download.open(); }
void close() { m_download.close(); }
void hash_resume_save() { m_download.hash_resume_save(); }
bool operator == (const std::string& str) { return str == m_download.get_hash(); }
private:
+11 -1
View File
@@ -23,6 +23,7 @@
#include "config.h"
#include <algorithm>
#include <sigc++/bind.h>
#include <torrent/torrent.h>
#include "rak/functional.h"
@@ -38,14 +39,18 @@ DownloadList::insert(std::istream* str) {
iterator itr = Base::insert(end(), new Download);
(*itr)->set_download(d);
(*itr)->get_download().signal_download_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::finished), *itr));
m_slotMapInsert.for_each(*itr);
return itr;
}
DownloadList::iterator
DownloadList::erase(iterator itr) {
(*itr)->release_download();
m_slotMapErase.for_each(*itr);
(*itr)->release_download();
torrent::download_remove((*itr)->get_hash());
delete *itr;
@@ -59,4 +64,9 @@ DownloadList::clear() {
Base::clear();
}
void
DownloadList::finished(Download* d) {
m_slotMapFinished.for_each(d);
}
}
+31 -3
View File
@@ -26,6 +26,8 @@
#include <iosfwd>
#include <list>
#include "download_slot_map.h"
namespace core {
class Download;
@@ -51,11 +53,37 @@ public:
~DownloadList() { clear(); }
iterator insert(std::istream* str);
iterator erase(iterator itr);
iterator insert(std::istream* str);
iterator erase(iterator itr);
void open(Download* d) { m_slotMapOpen.for_each(d); }
void close(Download* d) { m_slotMapClose.for_each(d); }
void start(Download* d) { m_slotMapStart.for_each(d); }
void stop(Download* d) { m_slotMapStop.for_each(d); }
DownloadSlotMap& slot_map_insert() { return m_slotMapInsert; }
DownloadSlotMap& slot_map_erase() { return m_slotMapErase; }
DownloadSlotMap& slot_map_open() { return m_slotMapOpen; }
DownloadSlotMap& slot_map_close() { return m_slotMapClose; }
DownloadSlotMap& slot_map_start() { return m_slotMapStart; }
DownloadSlotMap& slot_map_stop() { return m_slotMapStop; }
DownloadSlotMap& slot_map_finished() { return m_slotMapFinished; }
private:
void clear();
void clear();
void finished(Download* d);
DownloadSlotMap m_slotMapInsert;
DownloadSlotMap m_slotMapErase;
DownloadSlotMap m_slotMapOpen;
DownloadSlotMap m_slotMapClose;
DownloadSlotMap m_slotMapStart;
DownloadSlotMap m_slotMapStop;
DownloadSlotMap m_slotMapFinished;
};
}
+2 -2
View File
@@ -36,9 +36,9 @@ public:
typedef sigc::slot1<void, Download*> SlotDownload;
typedef std::map<std::string, SlotDownload> Base;
void insert(const std::string& key, SlotDownload s) { Base::operator[](key) = s; }
void insert(const std::string& key, SlotDownload s) { Base::operator[](key) = s; }
void for_each(Download* d);
void for_each(Download* d);
};
inline void
+13 -13
View File
@@ -54,36 +54,36 @@ public:
using Base::empty;
using Base::size;
void insert(Download* d, Slot s);
void insert(Download* d, Slot s);
// It's safe to try to remove downloads not in the queue. The hash
// checking is not stopped if it has already started.
void remove(Download* d);
void remove(Download* d);
iterator find(Download* d);
iterator find(Download* d);
private:
void receive_hash_done(Download* d);
void receive_hash_done(Download* d);
void fill_queue();
void fill_queue();
};
class HashQueueNode {
public:
HashQueueNode(Download* d, HashQueue::Slot s) : m_download(d), m_slot(s) {}
~HashQueueNode() { disconnect(); }
~HashQueueNode() { disconnect(); }
void disconnect() { m_connection.disconnect(); }
void disconnect() { m_connection.disconnect(); }
Download* get_download() { return m_download; }
HashQueue::Slot get_slot() { return m_slot; }
Download* get_download() { return m_download; }
HashQueue::Slot get_slot() { return m_slot; }
void set_connection(sigc::connection c) { m_connection = c; }
void set_connection(sigc::connection c) { m_connection = c; }
private:
Download* m_download;
HashQueue::Slot m_slot;
sigc::connection m_connection;
Download* m_download;
HashQueue::Slot m_slot;
sigc::connection m_connection;
};
}
+69 -61
View File
@@ -27,9 +27,8 @@
#include <cstring>
#include <fstream>
#include <istream>
#include <sstream>
#include <iterator>
#include <sigc++/bind.h>
#include <sigc++/hide.h>
#include <torrent/bencode.h>
#include <torrent/exceptions.h>
#include <torrent/torrent.h>
@@ -40,6 +39,11 @@
namespace core {
static void
connect_signal_network_log(Download* d, torrent::Download::SlotString s) {
d->get_download().signal_network_log(s);
}
void
Manager::initialize() {
torrent::Http::set_factory(m_poll.get_http_factory());
@@ -47,12 +51,32 @@ Manager::initialize() {
CurlStack::init();
//torrent::initialize();
if (!torrent::listen_open(m_portFirst, m_portLast))
throw std::runtime_error("Could not open port for listening.");
// Register log signals.
// Register slots to be called when a download is inserted/erased,
// opened or closed.
m_downloadList.slot_map_insert().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().insert("2_manager_start", sigc::mem_fun(*this, &Manager::start));
m_downloadList.slot_map_insert().insert("3_store_save", sigc::mem_fun(m_downloadStore, &DownloadStore::save));
m_downloadList.slot_map_erase().insert("1_hash_queue_remove", sigc::mem_fun(m_hashQueue, &HashQueue::remove));
m_downloadList.slot_map_erase().insert("1_store_remove", sigc::mem_fun(m_downloadStore, &DownloadStore::remove));
m_downloadList.slot_map_open().insert("1_download_open", sigc::mem_fun(&Download::open));
// Currently does not call stop, might want to add a function that
// checks if we're running, and if so stop?
m_downloadList.slot_map_close().insert("1_download_close", sigc::mem_fun(&Download::close));
m_downloadList.slot_map_close().insert("1_hash_queue_remove", sigc::mem_fun(m_hashQueue, &HashQueue::remove));
m_downloadList.slot_map_start().insert("1_download_start", sigc::mem_fun(&Download::start));
m_downloadList.slot_map_stop().insert("1_download_stop", sigc::mem_fun(&Download::stop));
m_downloadList.slot_map_stop().insert("2_hash_resume_save", sigc::mem_fun(&Download::hash_resume_save));
m_downloadList.slot_map_stop().insert("3_store_save", sigc::mem_fun(m_downloadStore, &DownloadStore::save));
//m_downloadList.slot_map_finished().insert("1_check_hash", sigc::mem_fun(*this, &Manager::check_hash));
}
void
@@ -66,10 +90,12 @@ Manager::cleanup() {
void
Manager::insert(std::string uri) {
if (std::strncmp(uri.c_str(), "http://", 7))
create_file(uri);
else
if (std::strncmp(uri.c_str(), "http://", 7) == 0) {
create_http(uri);
} else {
std::fstream f(uri.c_str(), std::ios::in);
create_final(&f);
}
}
Manager::iterator
@@ -80,9 +106,6 @@ Manager::erase(DownloadList::iterator itr) {
if (!(*itr)->get_download().is_open())
throw std::logic_error("core::Manager::erase(...) called on an closed download");
m_hashQueue.remove(*itr);
m_downloadStore.remove(*itr);
return m_downloadList.erase(itr);
}
@@ -93,13 +116,13 @@ Manager::start(Download* d) {
return;
if (!d->get_download().is_open())
d->open();
m_downloadList.open(d);
if (d->get_download().is_hash_checked())
d->start();
m_downloadList.start(d);
else
// This can cause infinit loops.
m_hashQueue.insert(d, sigc::mem_fun(d, &Download::start));
m_hashQueue.insert(d, sigc::bind(sigc::mem_fun(m_downloadList, &DownloadList::start), d));
} catch (torrent::local_error& e) {
m_logImportant.push_front(e.what());
@@ -110,13 +133,7 @@ Manager::start(Download* d) {
void
Manager::stop(Download* d) {
try {
m_hashQueue.remove(d);
d->stop();
if (d->get_download().is_hash_checked())
d->get_download().hash_save();
m_downloadStore.save(d);
m_downloadList.stop(d);
} catch (torrent::local_error& e) {
m_logImportant.push_front(e.what());
@@ -125,17 +142,34 @@ Manager::stop(Download* d) {
}
void
Manager::receive_http_failed(std::string msg) {
m_logImportant.push_front("Http download error: \"" + msg + "\"");
m_logComplete.push_front("Http download error: \"" + msg + "\"");
}
Manager::check_hash(Download* d) {
bool restart = d->get_download().is_active();
void
Manager::create_file(const std::string& uri) {
std::fstream f(uri.c_str(), std::ios::in);
create_final(&f);
}
try {
if (d->get_download().is_active())
m_downloadList.stop(d);
m_downloadList.close(d);
d->get_download().hash_resume_clear();
m_downloadList.open(d);
if (d->get_download().is_hash_checking() ||
d->get_download().is_hash_checked())
throw std::logic_error("Manager::check_hash(...) closed the torrent but is_hash_check{ing,ed}() == true");
if (m_hashQueue.find(d) != m_hashQueue.end())
throw std::logic_error("Manager::check_hash(...) closed the torrent but it was found in m_hashQueue");
if (restart)
m_hashQueue.insert(d, sigc::bind(sigc::mem_fun(m_downloadList, &DownloadList::start), d));
else
m_hashQueue.insert(d, sigc::slot0<void>());
} catch (torrent::local_error& e) {
m_logImportant.push_front(e.what());
m_logComplete.push_front(e.what());
}
}
void
Manager::create_http(const std::string& uri) {
@@ -149,12 +183,7 @@ Manager::create_http(const std::string& uri) {
void
Manager::create_final(std::istream* s) {
try {
iterator itr = m_downloadList.insert(s);
setup_download(*itr);
start(*itr);
m_downloadStore.save(*itr);
m_downloadList.insert(s);
} catch (torrent::local_error& e) {
// What to do? Keep in list for now.
@@ -164,30 +193,9 @@ Manager::create_final(std::istream* s) {
}
void
Manager::setup_download(Download* d) {
m_defaultSettings.for_each(d);
if (m_debugTracker >= 0)
d->get_download().signal_tracker_dump(sigc::mem_fun(*this, &Manager::receive_debug_tracker));
// If we want to monitor network stuff.
d->get_download().signal_network_log(sigc::mem_fun(m_logComplete, &Log::push_front));
}
void
Manager::receive_debug_tracker(std::istream* s) {
std::stringstream filename;
filename << "./tracker_dump." << m_debugTracker++;
std::fstream out(filename.str().c_str(), std::ios::out | std::ios::trunc);
if (!out.is_open())
return;
s->seekg(0);
std::copy(std::istream_iterator<char>(*s), std::istream_iterator<char>(),
std::ostream_iterator<char>(out));
Manager::receive_http_failed(std::string msg) {
m_logImportant.push_front("Http download error: \"" + msg + "\"");
m_logComplete.push_front("Http download error: \"" + msg + "\"");
}
}
+1 -11
View File
@@ -26,7 +26,6 @@
#include <iosfwd>
#include "download_list.h"
#include "download_slot_map.h"
#include "download_store.h"
#include "hash_queue.h"
#include "http_queue.h"
@@ -52,8 +51,6 @@ public:
HashQueue& get_hash_queue() { return m_hashQueue; }
HttpQueue& get_http_queue() { return m_httpQueue; }
DownloadSlotMap& get_default_settings() { return m_defaultSettings; }
Poll& get_poll() { return m_poll; }
Log& get_log_important() { return m_logImportant; }
Log& get_log_complete() { return m_logComplete; }
@@ -74,24 +71,17 @@ public:
void debug_tracker() { m_debugTracker = 0; }
private:
void receive_http_failed(std::string msg);
void create_file(const std::string& uri);
void create_http(const std::string& uri);
void create_final(std::istream* s);
void setup_download(Download* itr);
void receive_debug_tracker(std::istream* s);
void receive_http_failed(std::string msg);
DownloadList m_downloadList;
DownloadStore m_downloadStore;
HashQueue m_hashQueue;
HttpQueue m_httpQueue;
DownloadSlotMap m_defaultSettings;
Poll m_poll;
Log m_logImportant;
Log m_logComplete;