mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-10-07 14:49:21 +00:00
Adding hash check queue.
git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@278 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
SUBDIRS = src
|
SUBDIRS = src
|
||||||
|
|
||||||
EXTRA_DIST= \
|
EXTRA_DIST= \
|
||||||
autogen.sh
|
autogen.sh \
|
||||||
|
scripts/checks.m4
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ libsub_core_a_SOURCES = \
|
|||||||
curl_get.h \
|
curl_get.h \
|
||||||
curl_stack.cc \
|
curl_stack.cc \
|
||||||
curl_stack.h \
|
curl_stack.h \
|
||||||
|
hash_queue.cc \
|
||||||
|
hash_queue.h \
|
||||||
http_queue.cc \
|
http_queue.cc \
|
||||||
http_queue.h \
|
http_queue.h \
|
||||||
download.cc \
|
download.cc \
|
||||||
|
|||||||
+1
-2
@@ -19,10 +19,9 @@ public:
|
|||||||
void open() { m_download.open(); }
|
void open() { m_download.open(); }
|
||||||
void close() { m_download.close(); }
|
void close() { m_download.close(); }
|
||||||
|
|
||||||
|
void start() { m_download.start(); }
|
||||||
void stop() { m_download.stop(); }
|
void stop() { m_download.stop(); }
|
||||||
|
|
||||||
void hash_check(bool resume = false) { m_download.hash_check(resume); }
|
|
||||||
|
|
||||||
bool operator == (const std::string& str) { return str == m_download.get_hash(); }
|
bool operator == (const std::string& str) { return str == m_download.get_hash(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ DownloadList::insert(std::istream* str) {
|
|||||||
iterator itr = Base::insert(end(), Download());
|
iterator itr = Base::insert(end(), Download());
|
||||||
|
|
||||||
itr->set_download(d);
|
itr->set_download(d);
|
||||||
itr->get_download().signal_hash_done(sigc::bind(sigc::mem_fun(*this, &DownloadList::receive_hash_done),
|
|
||||||
itr->get_hash()));
|
|
||||||
|
|
||||||
return itr;
|
return itr;
|
||||||
}
|
}
|
||||||
@@ -32,14 +30,4 @@ DownloadList::erase(iterator itr) {
|
|||||||
Base::erase(itr);
|
Base::erase(itr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
DownloadList::receive_hash_done(const std::string& str) {
|
|
||||||
iterator itr = std::find(begin(), end(), str);
|
|
||||||
|
|
||||||
if (itr == end())
|
|
||||||
throw torrent::client_error("DownloadList received hash check done, but couldn't find the download");
|
|
||||||
|
|
||||||
itr->get_download().start();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ public:
|
|||||||
|
|
||||||
iterator insert(std::istream* str);
|
iterator insert(std::istream* str);
|
||||||
void erase(iterator itr);
|
void erase(iterator itr);
|
||||||
|
|
||||||
private:
|
|
||||||
void receive_hash_done(const std::string& str);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <sigc++/bind.h>
|
||||||
|
|
||||||
|
#include "download.h"
|
||||||
|
#include "functional.h"
|
||||||
|
#include "hash_queue.h"
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
void
|
||||||
|
HashQueue::insert(Download* d, Slot s) {
|
||||||
|
if (std::find_if(begin(), end(), func::equal(d, std::mem_fun(&HashQueueNode::get_download))) != end())
|
||||||
|
throw std::logic_error("core::HashQueue::insert(...) received a Download that is already queued");
|
||||||
|
|
||||||
|
if (d->get_download().is_hash_checked()) {
|
||||||
|
s();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator itr = Base::insert(end(), new HashQueueNode(d, s));
|
||||||
|
|
||||||
|
(*itr)->set_connection(d->get_download().signal_hash_done(sigc::bind(sigc::mem_fun(*this, &HashQueue::receive_hash_done), itr)));
|
||||||
|
|
||||||
|
fill_queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HashQueue::remove(Download* d) {
|
||||||
|
iterator itr = std::find_if(begin(), end(), func::equal(d, std::mem_fun(&HashQueueNode::get_download)));
|
||||||
|
|
||||||
|
if (itr == end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((*itr)->get_download()->get_download().is_hash_checking())
|
||||||
|
// What do we do if we're already checking?
|
||||||
|
;
|
||||||
|
|
||||||
|
delete *itr;
|
||||||
|
Base::erase(itr);
|
||||||
|
|
||||||
|
fill_queue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HashQueue::receive_hash_done(Base::iterator itr) {
|
||||||
|
Slot s = (*itr)->get_slot();
|
||||||
|
|
||||||
|
delete *itr;
|
||||||
|
Base::erase(itr);
|
||||||
|
|
||||||
|
s();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HashQueue::fill_queue() {
|
||||||
|
if (empty() || front()->get_download()->get_download().is_hash_checking())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (front()->get_download()->get_download().is_hash_checked())
|
||||||
|
throw std::logic_error("core::HashQueue::fill_queue() encountered a checked hash");
|
||||||
|
|
||||||
|
front()->get_download()->get_download().hash_check();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#ifndef RTORRENT_CORE_HASH_QUEUE_H
|
||||||
|
#define RTORRENT_CORE_HASH_QUEUE_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <sigc++/slot.h>
|
||||||
|
#include <sigc++/connection.h>
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
class Download;
|
||||||
|
|
||||||
|
class HashQueueNode;
|
||||||
|
|
||||||
|
class HashQueue : private std::list<HashQueueNode*> {
|
||||||
|
public:
|
||||||
|
typedef std::list<HashQueueNode*> Base;
|
||||||
|
typedef sigc::slot0<void> Slot;
|
||||||
|
|
||||||
|
using Base::iterator;
|
||||||
|
using Base::const_iterator;
|
||||||
|
using Base::reverse_iterator;
|
||||||
|
using Base::const_reverse_iterator;
|
||||||
|
|
||||||
|
using Base::begin;
|
||||||
|
using Base::end;
|
||||||
|
using Base::rbegin;
|
||||||
|
using Base::rend;
|
||||||
|
|
||||||
|
using Base::front;
|
||||||
|
using Base::back;
|
||||||
|
|
||||||
|
using Base::empty;
|
||||||
|
using Base::size;
|
||||||
|
|
||||||
|
// Should it be safe to try inserting already present/checked downloads?
|
||||||
|
void insert(Download* d, Slot s);
|
||||||
|
|
||||||
|
// It's safe to try to remove downloads not in the queue.
|
||||||
|
void remove(Download* d);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void receive_hash_done(Base::iterator itr);
|
||||||
|
|
||||||
|
void fill_queue();
|
||||||
|
};
|
||||||
|
|
||||||
|
class HashQueueNode {
|
||||||
|
public:
|
||||||
|
HashQueueNode(Download* d, HashQueue::Slot s) : m_download(d), m_slot(s) {}
|
||||||
|
~HashQueueNode() { m_connection.disconnect(); }
|
||||||
|
|
||||||
|
Download* get_download() { return m_download; }
|
||||||
|
HashQueue::Slot get_slot() { return m_slot; }
|
||||||
|
|
||||||
|
void set_connection(sigc::connection c) { m_connection = c; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Download* m_download;
|
||||||
|
HashQueue::Slot m_slot;
|
||||||
|
sigc::connection m_connection;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+17
-4
@@ -19,6 +19,21 @@ Manager::insert(const std::string& uri) {
|
|||||||
create_http(uri);
|
create_http(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::start(Download* d) {
|
||||||
|
if (d->get_download().is_active())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d->get_download().is_open()) {
|
||||||
|
d->start();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
d->open();
|
||||||
|
|
||||||
|
m_hashQueue.insert(d, sigc::mem_fun(*d, &Download::start));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Manager::create_file(const std::string& uri) {
|
Manager::create_file(const std::string& uri) {
|
||||||
DownloadList::iterator itr = m_downloadList.end();
|
DownloadList::iterator itr = m_downloadList.end();
|
||||||
@@ -28,8 +43,7 @@ Manager::create_file(const std::string& uri) {
|
|||||||
|
|
||||||
itr = m_downloadList.insert(&f);
|
itr = m_downloadList.insert(&f);
|
||||||
|
|
||||||
itr->open();
|
start(&*itr);
|
||||||
itr->hash_check();
|
|
||||||
|
|
||||||
} catch (torrent::local_error& e) {
|
} catch (torrent::local_error& e) {
|
||||||
// What to do? Keep in list for now.
|
// What to do? Keep in list for now.
|
||||||
@@ -51,8 +65,7 @@ Manager::receive_http_done(torrent::Http* http) {
|
|||||||
try {
|
try {
|
||||||
itr = m_downloadList.insert(http->get_stream());
|
itr = m_downloadList.insert(http->get_stream());
|
||||||
|
|
||||||
itr->open();
|
start(&*itr);
|
||||||
itr->hash_check();
|
|
||||||
|
|
||||||
} catch (torrent::local_error& e) {
|
} catch (torrent::local_error& e) {
|
||||||
// What to do? Keep in list for now.
|
// What to do? Keep in list for now.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define RTORRENT_CORE_MANAGER_H
|
#define RTORRENT_CORE_MANAGER_H
|
||||||
|
|
||||||
#include "download_list.h"
|
#include "download_list.h"
|
||||||
|
#include "hash_queue.h"
|
||||||
#include "http_queue.h"
|
#include "http_queue.h"
|
||||||
|
|
||||||
namespace core {
|
namespace core {
|
||||||
@@ -12,10 +13,13 @@ public:
|
|||||||
typedef sigc::slot0<void> SlotFailed;
|
typedef sigc::slot0<void> SlotFailed;
|
||||||
|
|
||||||
DownloadList& get_download_list() { return m_downloadList; }
|
DownloadList& get_download_list() { return m_downloadList; }
|
||||||
|
HashQueue& get_hash_queue() { return m_hashQueue; }
|
||||||
HttpQueue& get_http_queue() { return m_httpQueue; }
|
HttpQueue& get_http_queue() { return m_httpQueue; }
|
||||||
|
|
||||||
void insert(const std::string& uri);
|
void insert(const std::string& uri);
|
||||||
|
|
||||||
|
void start(Download* d);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void receive_http_done(torrent::Http* http);
|
void receive_http_done(torrent::Http* http);
|
||||||
|
|
||||||
@@ -23,6 +27,7 @@ private:
|
|||||||
void create_http(const std::string& uri);
|
void create_http(const std::string& uri);
|
||||||
|
|
||||||
DownloadList m_downloadList;
|
DownloadList m_downloadList;
|
||||||
|
HashQueue m_hashQueue;
|
||||||
HttpQueue m_httpQueue;
|
HttpQueue m_httpQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user