Browse Source

- Do no pause torrents before saving fastresume data anymore (no longer needed)

- Save fast resume data regularly (every 10 seconds) to avoid downloading from s
cratch when qBittorrent restart
adaptive-webui-19844
Christophe Dumez 17 years ago
parent
commit
3ef0c82a8c
  1. 66
      src/bittorrent.cpp
  2. 6
      src/bittorrent.h

66
src/bittorrent.cpp

@ -58,6 +58,9 @@ bittorrent::bittorrent() : timerScan(0), DHTEnabled(false), preAllocateAll(false
ETARefresher = new QTimer(); ETARefresher = new QTimer();
connect(ETARefresher, SIGNAL(timeout()), this, SLOT(updateETAs())); connect(ETARefresher, SIGNAL(timeout()), this, SLOT(updateETAs()));
ETARefresher->start(ETA_REFRESH_INTERVAL); ETARefresher->start(ETA_REFRESH_INTERVAL);
fastResumeSaver = new QTimer();
connect(fastResumeSaver, SIGNAL(timeout()), this, SLOT(saveFastResumeAndRatioData()));
fastResumeSaver->start(10000);
// To download from urls // To download from urls
downloader = new downloadThread(this); downloader = new downloadThread(this);
connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString))); connect(downloader, SIGNAL(downloadFinished(QString, QString)), this, SLOT(processDownloadedFile(QString, QString)));
@ -73,6 +76,7 @@ bittorrent::~bittorrent() {
disableDirectoryScanning(); disableDirectoryScanning();
// Delete our objects // Delete our objects
delete deleter; delete deleter;
delete fastResumeSaver;
delete timerAlerts; delete timerAlerts;
delete ETARefresher; delete ETARefresher;
delete downloader; delete downloader;
@ -93,7 +97,7 @@ void bittorrent::preAllocateAllFiles(bool b) {
qDebug("/!\\ Error: Invalid handle"); qDebug("/!\\ Error: Invalid handle");
continue; continue;
} }
pauseAndReloadTorrent(h, b); reloadTorrent(h, b);
} }
} }
} }
@ -233,10 +237,6 @@ void bittorrent::deleteTorrent(QString hash, bool permanent) {
ETAs.remove(hash); ETAs.remove(hash);
// Remove tracker errors // Remove tracker errors
trackersErrors.remove(hash); trackersErrors.remove(hash);
// Remove from reloadingTorrents if reloading
if(reloadingTorrents.contains(hash)) {
reloadingTorrents.remove(hash);
}
// Remove it from ratio table // Remove it from ratio table
ratioData.remove(hash); ratioData.remove(hash);
int index = finishedTorrents.indexOf(hash); int index = finishedTorrents.indexOf(hash);
@ -823,8 +823,7 @@ void bittorrent::saveDownloadUploadForTorrent(QString hash) {
ratio_file.close(); ratio_file.close();
} }
// Save fastresume data for all torrents // Save fastresume data for all torrents (called periodically)
// and remove them from the session
void bittorrent::saveFastResumeAndRatioData() { void bittorrent::saveFastResumeAndRatioData() {
qDebug("Saving fast resume and ratio data"); qDebug("Saving fast resume and ratio data");
QString file; QString file;
@ -834,20 +833,9 @@ void bittorrent::saveFastResumeAndRatioData() {
if(! torrentBackup.exists()) { if(! torrentBackup.exists()) {
torrentBackup.mkpath(torrentBackup.path()); torrentBackup.mkpath(torrentBackup.path());
} }
// Pause torrents
std::vector<torrent_handle> handles = s->get_torrents(); std::vector<torrent_handle> handles = s->get_torrents();
for(unsigned int i=0; i<handles.size(); ++i) { // It is not necessary to pause the torrents before saving fastresume data anymore
QTorrentHandle h = handles[i]; // because we either use Full allocation or sparse mode.
if(!h.is_valid()) {
qDebug("/!\\ Error: Invalid handle");
continue;
}
// Pause download (needed before fast resume writing)
if(!h.is_paused()){
waitingForPause << h.hash();
h.pause();
}
}
// Write fast resume data // Write fast resume data
for(unsigned int i=0; i<handles.size(); ++i) { for(unsigned int i=0; i<handles.size(); ++i) {
QTorrentHandle h = handles[i]; QTorrentHandle h = handles[i];
@ -856,11 +844,6 @@ void bittorrent::saveFastResumeAndRatioData() {
continue; continue;
} }
QString hash = h.hash(); QString hash = h.hash();
while(waitingForPause.contains(hash)) {
//qDebug("Sleeping while waiting that %s is paused", misc::toString(h.info_hash()).c_str());
SleeperThread::msleep(300);
readAlerts();
}
// Extracting resume data // Extracting resume data
if (h.has_metadata()) { if (h.has_metadata()) {
if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+".torrent")) { if(QFile::exists(torrentBackup.path()+QDir::separator()+hash+".torrent")) {
@ -878,8 +861,6 @@ void bittorrent::saveFastResumeAndRatioData() {
// Save trackers // Save trackers
saveTrackerFile(hash); saveTrackerFile(hash);
} }
// Remove torrent
s->remove_torrent(h.get_torrent_handle());
} }
qDebug("Fast resume and ratio data saved"); qDebug("Fast resume and ratio data saved");
} }
@ -1126,21 +1107,6 @@ void bittorrent::readAlerts() {
} }
} }
} }
else if (torrent_paused_alert* p = dynamic_cast<torrent_paused_alert*>(a.get())) {
QTorrentHandle h(p->handle);
if(h.is_valid()){
QString hash = h.hash();
qDebug("Received torrent_paused_alert for %s", hash.toUtf8().data());
int index = waitingForPause.indexOf(hash);
if(index != -1){
waitingForPause.removeAt(index);
}
if(reloadingTorrents.contains(hash)) {
reloadTorrent(h, reloadingTorrents.value(hash));
reloadingTorrents.remove(hash);
}
}
}
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) { else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get())) {
emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str())); emit peerBlocked(QString::fromUtf8(p->ip.to_string().c_str()));
} }
@ -1181,22 +1147,6 @@ QStringList bittorrent::getTorrentsToPauseAfterChecking() const{
return torrentsToPauseAfterChecking; return torrentsToPauseAfterChecking;
} }
// Function to reload the torrent async after the torrent is actually
// paused so that we can get fastresume data
void bittorrent::pauseAndReloadTorrent(QTorrentHandle h, bool full_alloc) {
if(!h.is_valid()) {
std::cerr << "/!\\ Error: Invalid handle\n";
return;
}
// ask to pause the torrent (async)
h.pause();
QString hash = h.hash();
// Add it to reloadingTorrents has table so that we now we
// we should reload the torrent once we receive the
// torrent_paused_alert. pause() is async now...
reloadingTorrents[hash] = full_alloc;
}
// Reload a torrent with full allocation mode // Reload a torrent with full allocation mode
void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) { void bittorrent::reloadTorrent(const QTorrentHandle &h, bool full_alloc) {
qDebug("** Reloading a torrent"); qDebug("** Reloading a torrent");

6
src/bittorrent.h

@ -44,18 +44,17 @@ class bittorrent : public QObject{
QString scan_dir; QString scan_dir;
QTimer *timerScan; QTimer *timerScan;
QTimer *timerAlerts; QTimer *timerAlerts;
QTimer *fastResumeSaver;
bool DHTEnabled; bool DHTEnabled;
downloadThread *downloader; downloadThread *downloader;
QString defaultSavePath; QString defaultSavePath;
QStringList torrentsToPauseAfterChecking; QStringList torrentsToPauseAfterChecking;
QHash<QString, bool> reloadingTorrents;
QHash<QString, QList<qlonglong> > ETAstats; QHash<QString, QList<qlonglong> > ETAstats;
QHash<QString, qlonglong> ETAs; QHash<QString, qlonglong> ETAs;
QHash<QString, QPair<size_type,size_type> > ratioData; QHash<QString, QPair<size_type,size_type> > ratioData;
QTimer *ETARefresher; QTimer *ETARefresher;
QHash<QString, QList<QPair<QString, QString> > > trackersErrors; QHash<QString, QList<QPair<QString, QString> > > trackersErrors;
deleteThread *deleter; deleteThread *deleter;
QStringList waitingForPause;
QStringList finishedTorrents; QStringList finishedTorrents;
QStringList unfinishedTorrents; QStringList unfinishedTorrents;
bool preAllocateAll; bool preAllocateAll;
@ -136,6 +135,7 @@ class bittorrent : public QObject{
void enableNATPMP(bool b); void enableNATPMP(bool b);
void enableLSD(bool b); void enableLSD(bool b);
bool enableDHT(bool b); bool enableDHT(bool b);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc);
protected slots: protected slots:
void scanDirectory(); void scanDirectory();
@ -143,8 +143,6 @@ class bittorrent : public QObject{
void processDownloadedFile(QString, QString); void processDownloadedFile(QString, QString);
bool loadTrackerFile(QString hash); bool loadTrackerFile(QString hash);
void saveTrackerFile(QString hash); void saveTrackerFile(QString hash);
void pauseAndReloadTorrent(QTorrentHandle h, bool full_alloc);
void reloadTorrent(const QTorrentHandle &h, bool full_alloc); // This is protected now, call pauseAndReloadTorrent() instead
void deleteBigRatios(); void deleteBigRatios();
signals: signals:

Loading…
Cancel
Save