Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toggle or stop download thread-safely #132

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ariadownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
#include "ariadownloader.h"
#include "system.h"

// libaria2 thread safety note:
// "Please keep in mind that only one Session object can be allowed per process due to the heavy use
// of static objects in aria2 code base. Session object is not safe for concurrent accesses from
// multiple threads. It must be used from one thread at a time. In general, libaria2 is not entirely
// thread-safe."

int downloadEventCallback(aria2::Session* session, aria2::DownloadEvent event,
aria2::A2Gid gid, void* userData)
{
Expand Down
8 changes: 8 additions & 0 deletions downloadworker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "quazip/quazip/JlCompress.h"
#include "settings.h"
#include "system.h"
#include <QApplication>
#include <QDebug>
#include <QDir>

Expand Down Expand Up @@ -149,6 +150,8 @@ void DownloadWorker::download()
auto start = std::chrono::steady_clock::now();
bool ret = true;
running_ = true;
// If the download is not making any progress, aria sleeps for 1 second each time it is called
// with RUN_ONCE. So this will not spin the CPU.
while (ret && running_) {
ret = downloader_.run();
auto now = std::chrono::steady_clock::now();
Expand All @@ -175,7 +178,12 @@ void DownloadWorker::download()
emit completedSizeChanged(completedSize_);
}
}

// Respond to Qt signals sent to the downloader thread, namely toggle or stop
QApplication::processEvents();
}

qDebug() << "Download loop exiting";
}

void DownloadWorker::toggle()
Expand Down
4 changes: 2 additions & 2 deletions downloadworker.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class DownloadWorker : public QObject, public AriaDownloader::DownloadCallback
void addTorrent(const std::string& uri);
void setDownloadDirectory(const std::string& dir);
void setConnectUrl(const QString& url);
void toggle();
void stop();

public slots:
void download();
void toggle();
void stop();

signals:
void downloadSpeedChanged(int speed);
Expand Down
5 changes: 3 additions & 2 deletions qmldownloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <QDir>
#include <QApplication>
#include <QDebug>
#include <QMetaObject>

#include "qmldownloader.h"
#include "system.h"
Expand Down Expand Up @@ -181,15 +182,15 @@ void QmlDownloader::toggleDownload(QString installPath)
startUpdate(installPath);
return;
}
worker_->toggle();
QMetaObject::invokeMethod(worker_, "toggle");
setState(state() == DOWNLOADING ? PAUSED : DOWNLOADING);
}

void QmlDownloader::stopAria()
{
if (worker_) {
qDebug() << "Stopping downloader thread";
worker_->stop();
QMetaObject::invokeMethod(worker_, "stop");
thread_.quit();
thread_.wait();
worker_ = nullptr;
Expand Down