mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-05 17:52:29 +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
|
||||
|
||||
EXTRA_DIST= \
|
||||
autogen.sh
|
||||
autogen.sh \
|
||||
scripts/checks.m4
|
||||
|
||||
@@ -5,6 +5,8 @@ libsub_core_a_SOURCES = \
|
||||
curl_get.h \
|
||||
curl_stack.cc \
|
||||
curl_stack.h \
|
||||
hash_queue.cc \
|
||||
hash_queue.h \
|
||||
http_queue.cc \
|
||||
http_queue.h \
|
||||
download.cc \
|
||||
|
||||
+1
-2
@@ -19,10 +19,9 @@ public:
|
||||
void open() { m_download.open(); }
|
||||
void close() { m_download.close(); }
|
||||
|
||||
void start() { m_download.start(); }
|
||||
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(); }
|
||||
|
||||
private:
|
||||
|
||||
@@ -17,8 +17,6 @@ DownloadList::insert(std::istream* str) {
|
||||
iterator itr = Base::insert(end(), Download());
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -32,14 +30,4 @@ DownloadList::erase(iterator 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);
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
Manager::create_file(const std::string& uri) {
|
||||
DownloadList::iterator itr = m_downloadList.end();
|
||||
@@ -28,8 +43,7 @@ Manager::create_file(const std::string& uri) {
|
||||
|
||||
itr = m_downloadList.insert(&f);
|
||||
|
||||
itr->open();
|
||||
itr->hash_check();
|
||||
start(&*itr);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
// What to do? Keep in list for now.
|
||||
@@ -51,8 +65,7 @@ Manager::receive_http_done(torrent::Http* http) {
|
||||
try {
|
||||
itr = m_downloadList.insert(http->get_stream());
|
||||
|
||||
itr->open();
|
||||
itr->hash_check();
|
||||
start(&*itr);
|
||||
|
||||
} catch (torrent::local_error& e) {
|
||||
// What to do? Keep in list for now.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define RTORRENT_CORE_MANAGER_H
|
||||
|
||||
#include "download_list.h"
|
||||
#include "hash_queue.h"
|
||||
#include "http_queue.h"
|
||||
|
||||
namespace core {
|
||||
@@ -12,10 +13,13 @@ public:
|
||||
typedef sigc::slot0<void> SlotFailed;
|
||||
|
||||
DownloadList& get_download_list() { return m_downloadList; }
|
||||
HashQueue& get_hash_queue() { return m_hashQueue; }
|
||||
HttpQueue& get_http_queue() { return m_httpQueue; }
|
||||
|
||||
void insert(const std::string& uri);
|
||||
|
||||
void start(Download* d);
|
||||
|
||||
private:
|
||||
void receive_http_done(torrent::Http* http);
|
||||
|
||||
@@ -23,6 +27,7 @@ private:
|
||||
void create_http(const std::string& uri);
|
||||
|
||||
DownloadList m_downloadList;
|
||||
HashQueue m_hashQueue;
|
||||
HttpQueue m_httpQueue;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user